我听说(可能是老师)应该在程序/函数之上声明所有变量,声明新的语句可能会导致问题。
但是随后我正在读K&R,我发现这句话:“变量声明(包括初始化)可以遵循引入任何复合语句的左括号,而不仅仅是开始函数的语句。 他以一个例子:
if (n > 0){ int i; for (i=0;i<n;i++) ... }我玩这个概念,甚至可以使用数组。 例如:
int main(){ int x = 0 ; while (x<10){ if (x>5){ int y[x]; y[0] = 10; printf("%d %d\n",y[0],y[4]); } x++; } }那么当我完全不允许声明变量? 例如,如果我的变量声明不正确的开头大括号呢? 像这里:
int main(){ int x = 10; x++; printf("%d\n",x); int z = 6; printf("%d\n",z); }这可能会因程序/机器而引起麻烦吗?
I heard (probably from a teacher) that one should declare all variables on top of the program/function, and that declaring new ones among the statements could cause problems.
But then I was reading K&R and I came across this sentence: "Declarations of variables (including initializations) may follow the left brace that introduces any compound statement, not just the one that begins a function". He follows with an example:
if (n > 0){ int i; for (i=0;i<n;i++) ... }I played a bit with the concept, and it works even with arrays. For example:
int main(){ int x = 0 ; while (x<10){ if (x>5){ int y[x]; y[0] = 10; printf("%d %d\n",y[0],y[4]); } x++; } }So when exactly I am not allowed to declare variables? For example, what if my variable declaration is not right after the opening brace? Like here:
int main(){ int x = 10; x++; printf("%d\n",x); int z = 6; printf("%d\n",z); }Could this cause trouble depending on the program/machine?
最满意答案
我也经常听到把变量放在函数的顶端是最好的办法,但我非常不同意。 我更愿意将变量限制在可能的最小范围内,这样他们的机会就越少,被滥用的机会就越少,所以我在程序的每一行都填满了我的精神空间。
虽然所有版本的C都允许使用词法块范围,但您可以声明变量取决于您所定位的C标准的版本:
C99或C ++
现代C编译器(如gcc和clang)支持C99和C11标准,允许您在语句可以随时声明变量。 变量的范围从声明点开始到块的结尾(下一个闭括号)。
if( x < 10 ){ printf("%d", 17); // z is not in scope in this line int z = 42; printf("%d", z); // z is in scope in this line }您也可以为循环初始化器声明变量。 该变量只存在于循环内。
for(int i=0; i<10; i++){ printf("%d", i); }ANSI C(C90)
如果您针对较早的ANSI C标准,这恰好是Microsoft MSVC编译器支持的最新版本,那么您只能在打开大括号1后立即声明变量。
这并不意味着你必须在函数的顶部声明所有的变量。 在C中,您可以在声明可以去的任何地方放置一个大括号分隔的块(不只是像if或者之类的东西),你可以用它来引入新的变量作用域。 以下是以前的C99示例的ANSI C版本:
if( x < 10 ){ printf("%d", 17); // z is not in scope in this line { int z = 42; printf("%d", z); // z is in scope in this line } } {int i; for(i=0; i<10; i++){ printf("%d", i); }}1请注意,如果您使用gcc,则需要传递--pedantic标志,使其实际上执行C90标准,并抱怨变量在错误的地方声明。 如果你只是使用-std=c90它使gcc接受C90的超集,这也允许更灵活的C99变量声明。
I also often hear that putting variables at the top of the function is the best way to do things, but I strongly disagree. I prefer to confine variables to the smallest scope possible so they have less chance to be misused and so I have less stuff filling up my mental space in each line on the program.
While all versions of C allow lexical block scope, where you can declare the variables depends of the version of the C standard that you are targeting:
C99 onwards or C++
Modern C compilers such as gcc and clang support the C99 and C11 standards, which allow you to declare a variable anywhere a statement could go. The variable's scope starts from the point of the declaration to the end of the block (next closing brace).
if( x < 10 ){ printf("%d", 17); // z is not in scope in this line int z = 42; printf("%d", z); // z is in scope in this line }You can also declare variables inside for loop initializers. The variable will only exist only inside the loop.
for(int i=0; i<10; i++){ printf("%d", i); }ANSI C (C90)
If you are targeting the older ANSI C standard, then you are limited to declaring variables immediately after an opening brace1.
This doesn't mean you have to declare all your variables at the top of your functions though. In C you can put a brace-delimited block anywhere a statement could go (not just after things like if or for) and you can use this to introduce new variable scopes. The following is the ANSI C version of the previous C99 examples:
if( x < 10 ){ printf("%d", 17); // z is not in scope in this line { int z = 42; printf("%d", z); // z is in scope in this line } } {int i; for(i=0; i<10; i++){ printf("%d", i); }}1 Note that if you are using gcc you need to pass the --pedantic flag to make it actually enforce the C90 standard and complain that the variables are declared in the wrong place. If you just use -std=c90 it makes gcc accept a superset of C90 which also allows the more flexible C99 variable declarations.
更多推荐
发布评论