当我第一次被介绍给C时,我被告知要始终在函数的顶部声明我的变量。现在我对语言有了很强的把握,我将重点放在编码风格上,特别是限制了变量的范围。我已经阅读了限制范围的好处,我遇到了一个有趣的例子。显然,C99允许你这样做......
for (int i = 0; i < 10; i++)
{
puts("hello");
}
我原本认为变量范围受到最内层周围花括号{ }
的限制,但在上面的例子中,int i
似乎受限于for循环的花括号,即使它是在它们之外声明的。
我尝试使用fgets()
扩展上面的示例来执行我认为类似的操作,但这两个都给了我一个语法错误。
fgets(char fpath[80], 80, stdin);
*见注**
fgets(char* fpath = malloc(80), 80, stdin);
那么,在C99中声明变量的确切位置是合法的吗? for循环示例是规则的例外吗?这是否也适用于while
和do while
循环?
*注意**:我甚至不确定这在语法上是否正确,即使我可以声明char数组,因为fgets()
正在寻找指向char的指针不是指向char 数组80的指针。这就是我尝试malloc()
版本的原因。
答案 0 :(得分:36)
在C99中,您可以在需要的位置声明变量,就像C ++允许您这样做。
void somefunc(char *arg)
{
char *ptr = "xyz";
if (strcmp(arg, ptr) == 0)
{
int abc = 0; /* Always could declare variables at a block start */
somefunc(arg, &ptr, &abc);
int def = another_func(abc, arg); /* New in C99 */
...other code using def, presumably...
}
}
您可以在'for'循环的控件部分声明一个变量:
for (int x = 0; x < 10; x++) /* New in C99 */
您不能在'while'循环或'if'语句的控制部分声明变量。
C99标准说:
6.8.5.3 for语句
声明
for ( clause-1 ; expression-2 ; expression-3 ) statement
表现如下:表达式表达式-2是控制表达式 在每次执行循环体之前进行评估。表达式-3表达式为 在每次执行循环体后评估为void表达式。如果第1条是a 声明,它声明的任何变量的范围是声明的剩余部分 整个循环,包括其他两个表达式;它是按执行顺序到达的 在第一次评估控制表达之前。如果子句-1是表达式,那么它是 在第一次评估控制表达之前评估为空表达。
答案 1 :(得分:8)
我要注意的第一件事是你不应该混淆
for (int i = 0; i < 10; i++) {
puts("hello");
}
和
fgets(char* fpath = malloc(80), 80, stdin);
第一个是控制结构,第二个是函数调用。控制结构以与函数调用完全不同的方式评估其parens()内的文本。
第二件事是......我不明白你想说的是什么:
如果你试图在for-loop体内使用i,编译器会立即给你一个错误。
你为for循环列出的代码是C中非常常见的结构,变量“i”确实应该在for循环体内可用。即,以下应该有效:
int n = 0;
for (int i = 0; i < 10; i++) {
n += i;
}
我误读你在说什么吗?
答案 2 :(得分:2)
关于for
/ fgets
混淆的底线是,虽然“封闭大括号控制范围”在大多数情况下是C中的正确规则,但在C99中还有另一条关于范围的规则(借用C ++),表示在控制结构的序言中声明的变量(即for
,while
,if
)在结构体中的范围内(并且是不在体外范围内。)