我在哪里可以合法地声明C99中的变量?
当我第一次被介绍到C时,我被告知总是在函数顶部声明变量。现在我对语言有了很强的掌握,我将精力集中在编码风格上,特别是限制变量的范围。我已经读到了限制范围的好处,我遇到了一个有趣的例子。显然,C99允许你这么做我在哪里可以合法地声明C99中的变量?,c,variables,declaration,C,Variables,Declaration,当我第一次被介绍到C时,我被告知总是在函数顶部声明变量。现在我对语言有了很强的掌握,我将精力集中在编码风格上,特别是限制变量的范围。我已经读到了限制范围的好处,我遇到了一个有趣的例子。显然,C99允许你这么做 for (int i = 0; i < 10; i++) { puts("hello"); } for(int i=0;iValue.< /P>>P>),你可以在需要的地方声明变量,就像C++允许你那样做。 void somefunc(char *arg) { cha
for (int i = 0; i < 10; i++)
{
puts("hello");
}
for(int i=0;i<10;i++)
{
放置(“你好”);
}
我原以为变量的作用域受到最里面的大括号{}
的限制,但在上面的示例中,inti
似乎受到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的指针。这就是为什么我在C99中尝试了MalCube(< /Cord>Value.< /P>>P>),你可以在需要的地方声明变量,就像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 */
行为如下:表达式-2是
在每次执行循环体之前进行评估。表达式-3是
在每次执行循环体后作为空表达式求值。如果第1条是
声明时,它声明的任何变量的范围都是声明的剩余部分,并且
整个循环,包括其他两个表达式;它是按执行顺序到达的
在第一次计算控制表达式之前。如果子句-1是表达式,则为
在对控制表达式进行第一次求值之前作为空表达式求值
我要注意的第一件事是你不应该混淆
for (int i = 0; i < 10; i++) {
puts("hello");
}
第一个是控制结构,第二个是函数调用。控件结构以与函数调用完全不同的方式计算其parens()中的文本
第二件事是。。。我不明白你想说什么:
如果您试图在for循环体中使用i,编译器将立即给您一个错误
您为for循环列出的代码是C中非常常见的结构,变量“i”应该确实在for循环体中可用。也就是说,以下方法应该有效:
int n = 0;
for (int i = 0; i < 10; i++) {
n += i;
}
int n=0;
对于(int i=0;i<10;i++){
n+=i;
}
我误解了你的意思吗?关于你的对于/fgets
的困惑是,虽然“封闭大括号控制范围”在大多数情况下在C中是正确的规则,但在C99中有另一个关于范围的规则(从C++借用)也就是说,在控制结构的序言中声明的变量(即
、while
、if
)在结构体的范围内(而不在结构体的范围外)。否,你没有误读,但很明显,我在我的问题中发布的SO链接上读到了一些不正确的信息,该链接说它不会编译。显然,更正确的语句应该是,如果不将-std=c99传递给gcc
,它将无法编译。你能提供一点关于控制结构中文本的评估与函数调用的更深入的见解吗,因为我认为这绝对是我的问题的根源。你链接的问题发布了一个for循环的示例,其中有一个逻辑错误,(注意for循环末尾的分号)由于那个逻辑错误,它将无法编译。这是一个非常常见的错误,对此有很多问题。感谢您的详细评论,参考标准§6.8.5.3很容易找到,但我没有发现允许在哪一个§中到处声明变量。有什么线索吗?@nowox-C11:语法将语句
和声明
列为出现在块项列表
中的块项
中的相同替代项。当然,函数体是一个复合语句。@nowox-相比之下,C90§6.6.2“复合语句或块”将复合语句列为{declaration list(opt)statement list(opt)}
,因此声明必须在一个块中的所有语句之前。显然,这只适用于for
循环,而+1则适用于answer.Oops。在C++中,如果<<代码> >代码> > ,我想我假设C99会借用整个东西,而不是只是< <代码> > < /Cult>部分。不管它是否合法,你都不应该调用Maloc,因为你没有检查它是否返回空值,您也无法释放正在分配的堆内存,因为fpath立即超出范围。至少在linux上,malloc很少返回null。并不是说不应该检查,但要记住,从malloc获得指针并不意味着实际上有足够的可用内存。
fgets(char* fpath = malloc(80), 80, stdin);
int n = 0;
for (int i = 0; i < 10; i++) {
n += i;
}