Why-for 循环中定义的变量在循环之外无法使用?

博主开始进入 java 学习阶段,在最近的练习中,发现了博文题目当初所提到的问题:为什么在 for 循环中定义的变量在循环之外无法使用?起初我以为java在for循环中直接int i可以较好的提现其比C语言的方便性(后查阅资料知在 C99开始就可以使用这种变量就近定义的方式来定义变量), 然而我发现当下一个 for 中使用 i 时却出现了错误提示。本文就从我暂时会用的编程语言来分析一下这个问题的本质。

for(int i = 0;i < 1;i++){
	int temp = 2;
}
System.out.println("i = " + i + ",temp = " + temp);

当运行本 java 程序是,发现会有如下报错就是说我在循环条件里面定义的 i 和循环体中定义的 temp 在循环之外都是不存在的。
《Java 语言程序设计》中有这样一段话:

如果变量只在循环中使用而不在其他地方使用,那么在 for 循环的出事动作中声明它是一个很好的变成习惯。如果在循环控制结构体中声明变量,那么在循环外不能引用它。

这句话其实已经交代了在 for循环中变量定义位置的问题。

其实变量定义位置不同就有不同的作用域,大部分语言规定用{ }来划分块作用域。for 循环就是一个块作用域,那么在此作用域中定义的变量只能在此作用域来使用,其实想想平时定义的函数中,形参是只能在本函数使用的,那么 for 也就是这个道理,括号中定义的变量只可以在紧跟着的块作用域来。这样就可以很好的理解题目中的疑问。

为了验证作用域的问题,我们重新拾起 vc6.0 来研究 C89中对变量定义的约束。C89规定,局部变量定义必须放在所有执行语句前,块开头处。那么我们在平时写C语言的时候,往往这样写:

#include "stdio.h"
int main()
{
	int i;
	int temp;
	for(i = 0;i < 1;i++){
		temp = 10;
	}
	printf("i=%d,temp=%d\n",i,temp);
}

的确大家也都这么做,把temp 变量定义在了最开始的位置,因为大部分同学也会觉得这样很合理。
然而经过上面的分析,我们知道 不只是函数块才叫块,for 循环也是一个块,那么 temp 也可以在 for 块作用域的开头处定义,即:

#include "stdio.h"
int main()
{
	int i;
	for(i = 0;i < 1;i++){
		int temp = 10;
		//......
	        printf("i=%d,temp=%d\n",i,temp);
	}
}

面对这串代码,可能有的小伙伴会脱口而出:”这串代码是错误的,因为temp不是在其他代码之上定义的”。

然而这串代码是正确的。

是不是对当初学的 C语言有点更深刻的理解?当然这个 temp 变量是不可以在 for 之外使用的。
这个例子同时说明了 块作用域 的问题。

所以,coding 的时候还是要好好理解一些作用域的。


More

接下来的问题就是说,我为什么还要在引言里说我要用我会的语言来讨论这个问题,因为我在查找文档的时候发现了这么一句话。

javascript中 for(){}要看这个语句所处的位置来看,在全局环境下定义那这个就是全局,定义函数中那就是局部,js中是以函数级作用域定义。

于是我用我仅有的 js 技能写了这串代码

<script>
for(var i = 0;i < 1;i++){
	var temp = 10;
}
alert("i = " + i + "temp = " + temp);
</script>

然后它巧妙的弹出了这个框。。。

因为我对 js 不是多么的熟悉,所以暂时记忆上面引用的这句话,挖个坑,等以后学会了再来填上:)