3 回答
TA贡献1946条经验 获得超3个赞
我也经常听到把变量放在函数顶部是最好的处理方法,但是我非常不同意。我更喜欢将变量限制在尽可能小的范围内,这样变量被滥用的机会就更少了,因此,在程序的每一行中填满我的思维空间的东西也就更少了。
尽管所有版本的C都允许词法块作用域,但是您可以在其中声明变量取决于目标C语言版本:
从C99开始或C ++
诸如gcc和clang之类的现代C编译器支持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循环初始化程序中声明变量。该变量仅在循环内部存在。
for(int i=0; i<10; i++){
printf("%d", i);
}
ANSI C(C90)
如果您以较早的ANSI C标准为目标,则仅限于在括号1之后立即声明变量。
但这并不意味着您必须在函数顶部声明所有变量。在C语言中,您可以将大括号分隔的块放在语句可以到达的任何位置(不仅在诸如if或之后for),并且可以使用它引入新的变量作用域。以下是以前的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变量声明。
TA贡献1777条经验 获得超10个赞
missingno介绍了ANSI C允许的内容,但是他没有说明为什么您的老师告诉您在函数顶部声明变量。在奇怪的地方声明变量会使您的代码更难阅读,并且可能导致错误。
以下面的代码为例。
#include <stdio.h>
int main() {
int i, j;
i = 20;
j = 30;
printf("(1) i: %d, j: %d\n", i, j);
{
int i;
i = 88;
j = 99;
printf("(2) i: %d, j: %d\n", i, j);
}
printf("(3) i: %d, j: %d\n", i, j);
return 0;
}
如您所见,我已经声明了i两次。好吧,更准确地说,我已经声明了两个变量,两个变量的名称均为i。您可能会认为这会导致错误,但是不会,因为两个i变量的作用域不同。当您查看此函数的输出时,可以更清楚地看到这一点。
(1) i: 20, j: 30
(2) i: 88, j: 99
(3) i: 20, j: 99
首先,我们分别为i和分配20和30 j。然后,在花括号内,我们指定88和99。那么,为什么要j保留其值,但又i回到20?这是由于两个不同的i变量。
在花括号的内部集合之间,i值20 的变量是隐藏的并且不可访问,但是由于我们尚未声明new j,因此我们仍在使用j外部作用域。当我们离开内部一组花括号时,i保持值88消失,我们再次可以访问i具有值20的。
有时候,这种行为是件好事,而有时却不是。但是应该清楚的是,如果不加选择地使用C的此功能,则确实会使代码混乱且难以理解。
TA贡献1871条经验 获得超8个赞
帖子显示以下代码:
//C99
printf("%d", 17);
int z=42;
printf("%d", z);
//ANSI C
printf("%d", 17);
{
int z=42;
printf("%d", z);
}
我认为这意味着它们是等效的。他们不是。如果将int z放置在此代码段的底部,则会对第一个z定义(而不对第二个z定义)引起重新定义错误。
但是,以下几行:
//C99
for(int i=0; i<10; i++){}
确实有效。显示了此C99规则的微妙之处。
就个人而言,我热情地避免使用此C99功能。
如这些示例所示,它缩小变量范围的说法是错误的。根据新规则,在扫描完整个块之前,您不能安全地声明变量,而以前,您只需要了解每个块顶部的情况。
- 3 回答
- 0 关注
- 526 浏览
添加回答
举报