考虑一下C程序的片段:
for(int i = 0; i < 5; i++)
{
int i = 10; // <- Note the local variable
printf("%d", i);
}
Run Code Online (Sandbox Code Playgroud)
它编译没有任何错误,并在执行时,它提供以下输出:
1010101010
Run Code Online (Sandbox Code Playgroud)
但是如果我在C++中编写类似的循环:
for(int i = 0; i < 5; i++)
{
int i = 10;
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
编译失败,出现此错误:
prog.cc:7:13: error: redeclaration of 'int i'
int i = 10;
^
prog.cc:5:13: note: 'int i' previously declared here
for(int i = 0; i < 5; i++)
^
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
das*_*ght 26
这是因为C和C++语言在嵌套在for
循环中的作用域中重新声明变量的规则不同:
C++
放入i
循环体的范围,所以第二个int i = 10
是重新声明,这是禁止的C
允许在for
循环内的范围内重新声明; 最里面的变量"胜利"这是一个正在运行的C程序的演示,以及一个无法编译的C++程序.
在正文中打开嵌套作用域修复了编译错误(演示):
for (int i =0 ; i != 5 ; i++) {
{
int i = 10;
cout << i << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
现在i
在for
标题中并且int i = 10
位于不同的范围内,因此允许程序运行.
hac*_*cks 21
与C不同,C++有规则,
C++ 11-§6.5.3/ 1:
该
for
声明for ( for-init-statement conditionopt ; expressionopt ) statement相当于
Run Code Online (Sandbox Code Playgroud){ for-init-statement while ( condition ) { statement expression ; } }
除了在for-init-statement中声明的名称与条件[...]中 声明的名称相同的声明区域
这意味着的是,范围for-init-statement
和statement
是相同的*和下面的代码将导致错误
for(int i = 0; i < 5; i++){
int i = 10; // Invalid.
// ...
}
Run Code Online (Sandbox Code Playgroud)
在C,
C11-§6.8.5/ 5中:
迭代语句是一个块,其范围是其封闭块范围的严格子集.循环体也是一个块,其范围是迭代语句范围的严格子集.
因此,statement
它有自己的范围,上面的代码是有效的和等价的
for(int i = 0; i < 5; i++){
{
int i = 10; // Valid.
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
建议阅读:n3337:6.5.1 while语句/ p(2).相同的参考资料可以在第9.5.1节和第9.5.3节中的c ++ 17 draft(n4659)中找到.