C99:我可以在“for”中的块开头声明变量吗?

C99:我可以在“for”中的块开头声明变量吗?,c,c99,c89,C,C99,C89,根据C99,以下代码是否合法 ... for(....) { int x = 4; ... } ... 您可以假设在第3行之前从未声明过变量x 到目前为止,我只发现了以下几点,但我认为这还不够: 块允许将一组声明和语句分组到一个语法单元中。 具有自动存储持续时间和可变长度的对象的初始值设定项 对具有块作用域的普通标识符的数组声明符进行求值,并对值进行排序 存储在对象中,包括在没有 每次按照执行顺序到达声明时的初始值设定项,就像它是一个 语句,并在每个声明中按声明符出现的顺序排列 这在C99和C

根据C99,以下代码是否合法

...
for(....) {
int x = 4;
...
}
...
您可以假设在第3行之前从未声明过变量x

到目前为止,我只发现了以下几点,但我认为这还不够:

块允许将一组声明和语句分组到一个语法单元中。 具有自动存储持续时间和可变长度的对象的初始值设定项 对具有块作用域的普通标识符的数组声明符进行求值,并对值进行排序 存储在对象中,包括在没有 每次按照执行顺序到达声明时的初始值设定项,就像它是一个 语句,并在每个声明中按声明符出现的顺序排列


这在C99和C89中都是合法的。
看看6.8.2,它定义了复合语句,这在C99和C89中都是合法的。
看看6.8.2,它定义了复合语句

是的,您可以在任何块的开头创建一个变量。变量在C++中输入时初始化,可以在块内的任何地方创建它们。

< P>是的,可以在任何块的开头创建变量。每次在C++中输入块时,变量都被初始化,可以在块内的任意位置创建变量。
for(....)
{
  int x=4;
  /*More code*/
}
是的,这在C99中是合法的,但不允许您在块后访问“x”。试图访问超出其范围的“x”将是未定义的行为


是的,这在C99中是合法的,但不允许您在块后访问“x”。试图访问超出其范围的“x”将是未定义的行为。

是的,您可以在C89中的块开始时在C99中的任何位置声明或定义变量

你说:

您可以假设在第3行之前 变量x从未声明过

即使以前声明过,也可以使用相同的名称声明新变量。这样做会阻止您访问该块中的旧变量

int x = 0;               /* old x */
printf("%d\n", x);       /* old x, prints 0 */
do {
    int x = 42;          /* new x */
    printf("%d\n", x);   /* new x, prints 42 */
} while (0);
printf("%d\n", x);       /* old x, prints 0 */
我从未在C99中尝试过以下操作。我真的不知道会发生什么: 我稍后会尝试,当我获得接近C99的编译器时


C99在任何地方声明/定义变量的功能并不是让我想更改的功能:

是的,您可以在C89块的开始处,在C99的任何地方声明或定义变量

你说:

您可以假设在第3行之前 变量x从未声明过

即使以前声明过,也可以使用相同的名称声明新变量。这样做会阻止您访问该块中的旧变量

int x = 0;               /* old x */
printf("%d\n", x);       /* old x, prints 0 */
do {
    int x = 42;          /* new x */
    printf("%d\n", x);   /* new x, prints 42 */
} while (0);
printf("%d\n", x);       /* old x, prints 0 */
我从未在C99中尝试过以下操作。我真的不知道会发生什么: 我稍后会尝试,当我获得接近C99的编译器时


C99在任何地方声明/定义变量的功能并不是让我想更改的功能:

在C99中,您也可以在任何地方创建变量。显示了我在C99中的编码程度:-在C99中,您也可以在任何地方创建变量。显示了我在C99中的编码程度:-您可以添加更多详细信息吗?我在三个案例中的哪一个?谢谢@quilby:在C89中,您可以在任何新作用域(即{}块)的开头声明变量。在C99中,您可以在范围内的任何地方声明变量。您知道这是在C89中首次引入的,还是在早期的C版本中出现的吗?你能再补充一点细节吗?我在三个案例中的哪一个?谢谢@quilby:在C89中,您可以在任何新作用域(即{}块)的开头声明变量。在C99中,您可以在范围内的任何地方声明变量。您知道这是在C89中首次引入的,还是在早期的C版本中出现的吗?老x。自动变量的作用域从定义的地方开始,一直到块的末尾。老实说,隐藏自动变量是一个相当可疑的问题。在块的开头声明它们并不能阻止有人尝试使用外部的x,而是获取内部的x,因为他们忘记了它在那里。如果你可以信任某人来处理隐藏变量,我认为你必须信任他们知道范围规则-如果你一直使用C99编译器,你也会很快知道它们,因为你知道如果外部x根本不存在,C99循环就不会编译。旧的x。自动变量的作用域从定义的地方开始,一直到块的末尾。老实说,隐藏自动变量是一个相当可疑的问题。在块的开头声明它们并不能阻止有人尝试使用外部的x,而是获取内部的x,因为他们忘记了它在那里。如果你可以信任某人来处理隐藏变量,我认为你必须信任他们知道作用域规则-如果你一直使用C99编译器,你也会很快知道它们,因为你会知道如果外部x在一个时间点不存在
这个C99循环不会编译。它不是未定义的行为。引用x超出其范围将是一个编译错误。这不是未定义的行为。引用x超出其范围将是一个编译错误。