好吧,我想知道为什么这段代码有效,我才意识到我在同一范围内有两个同名的变量。
我正在使用g ++(gcc 4.4)。
for(int k = 0 ; k < n ; k++)
{
while(true)
{
i = Tools::randomInt(0, n);
bool exists = false;
for(int k = 0 ; k < p_new_solution_size ; k++)
if( i == p_new_solution[k] )
{
exists = true;
break;
}
if(!exists)
break;
}
p_new_solution[p_new_solution_size] = i;
p_new_solution_size++;
}
答案 0 :(得分:10)
内部for循环中的k
阴影(或隐藏)外部for循环中的k
。
您可以在不同的范围内声明具有相同名称的多个变量。一个非常简单的例子如下:
int main()
{
int a; // 'a' refers to the int until it is shadowed or its block ends
{
float a; // 'a' refers to the float until the end of this block
} // 'a' now refers to the int again
}
答案 1 :(得分:4)
好吧,我想知道为什么这段代码有效,我才意识到我在同一范围内有两个同名的变量。
你似乎对范围感到困惑。它们不是“在同一”范围内...... for循环的k具有它自己的嵌套/内部范围。更重要的是,要了解语言允许的原因,请考虑:
#define DO_SOMETHING \
do { for (int i = 1; i <= 2; ++i) std::cout << i << '\n'; } while (false)
void f()
{
for (int i = 1; i <= 10; ++i)
DO_SOMETHING();
}
这里,由宏“DO_SOMETHING”替换的文本在与i相同的范围内进行评估。如果您正在编写DO_SOMETHING,则可能需要将其扩展为将某些内容存储在变量中,并确定标识符i
- 显然您无法知道它是否已存在于调用上下文中。您可以尝试选择一些更加模糊的东西,但是您会让人们使用这样的复杂变量名来表示他们的代码可维护性受到影响,并且迟早会发生冲突。因此,该语言只允许内部作用域引入具有相同名称的变量:使用最内部匹配直到其作用域退出。
即使你没有处理宏,也不得不停下来思考一些外部范围是否已经使用相同的名称。如果你知道你只是想要快速操作,你可以将它弹出一个独立的(嵌套的)范围而不考虑更大的上下文(只要你没有那些实际上想要使用外部范围变量的代码:如果你这样做那么你有时可以明确地指定它(如果它是由命名空间和类限定的,但如果它在函数体中,你最终需要更改自己的循环变量的名称(或者在引入同名之前创建一个引用或其他东西)变量))。
答案 2 :(得分:2)
从标准文档 Sec 3.3.1
每个名称都在程序文本的某些部分中引入,称为声明性区域,这是最大的部分 该名称有效的程序,也就是说,该名称可以用作非限定名称来引用该名称 同一实体。通常,每个特定名称仅在程序文本的某些可能不连续的部分内有效 称其范围。为了确定声明的范围,有时可以方便地参考声明的范围 声明。除非潜在范围包含另一个范围,否则声明的范围与其潜在范围相同 同名声明。在这种情况下,声明的潜在范围在内部(包含)声明中 区域被排除在外部(包含)声明区域中的声明范围之外。
在您第一次阅读时可能会让人感到困惑,但它确实回答了您的问题。
除非发生另一(内部)声明,否则潜在范围与声明范围相同。如果发生,外部声明的潜在范围已移除且仅内部声明已成立。
希望很清楚,这有助于......
答案 3 :(得分:1)
因为允许在同一范围内有两个同名的变量,但不能在同一个声明空间内。编译器采用适当名称的最本地变量,类似于使用名称X的成员变量“隐藏”名称X的全局变量。您应该收到警告。
答案 4 :(得分:0)
在C / C ++中,变量作用域受大括号的限制,因此以下代码对编译器有效:
int k()
{
int k;
{
int k;
{
int k;
}
}
}