为什么这个c++工作?(同名变量)

daolsyd0  于 2023-04-01  发布在  其他
关注(0)|答案(5)|浏览(129)

好了,我想知道为什么这段代码是工作的,我刚刚意识到,我有两个变量,在同一个范围内,具有相同的名称。
我使用的是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++;
    }
pzfprimi

pzfprimi1#

内部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
}
fd3cxomn

fd3cxomn2#

好了,我想知道为什么这段代码是工作的,我刚刚意识到,我有两个变量,在同一个范围内,具有相同的名称。
你似乎对作用域感到困惑。它们不是“在同一个”作用域内... 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-显然您无法知道它是否已经存在于调用上下文中。您可以尝试选择更模糊的内容,但是你会让人们使用如此复杂的变量名,以至于他们的代码可维护性受到影响,无论迟早都会发生冲突。所以,语言只是让内部作用域引入同名的变量:使用最里面的匹配,直到它的作用域退出。
即使你不处理宏,也要停下来想想是否有外部作用域已经使用了相同的名字,这是一件痛苦的事情。如果你知道你只是想要一个快速的操作,你可以把它弹出一个独立的(嵌套的)作用域,而不考虑更大的上下文(只要你没有真正想要使用外部作用域变量的代码:如果你这样做,那么你有时可以显式地指定它(如果它的范围是由命名空间和类,但如果它在函数体中,你最终需要改变自己的循环变量的名称(或在引入同名变量之前创建一个引用或其他东西))。

abithluo

abithluo3#

来自标准文档,* 第3.3.1节 *
每个名字都是在程序文本的某个部分引入的,称为声明区,声明区是程序中该名字有效的最大部分,也就是说,在声明区中该名字可以用作引用同一实体的非限定名。一般来说,每个特定的名字只在程序文本的某个可能不连续的部分(称为其作用域)中有效。要确定声明的作用域,有时引用声明的潜在作用域是方便的。2声明的作用域与其潜在作用域相同 除非潜在作用域包含同名的另一声明。3在这种情况下, * 内部声明的潜在作用域外部(包含)声明区域中的声明范围将排除外部(包含)声明区域。
在你第一次阅读时,这听起来可能令人困惑,但它确实回答了你的问题。
潜在作用域与声明的作用域相同,除非出现另一个(内部)声明。如果出现,外部声明的潜在作用域被 * 移除 *,而只是内部声明的作用域。
希望我清楚,它帮助..

ia2d9nvy

ia2d9nvy4#

因为你可以在同一个作用域中有两个同名的变量,但不能在同一个声明空间中。编译器会取最局部的变量,类似于你可以用一个名为X的成员变量来“隐藏”名为X的全局变量。不过你应该会得到一个警告。

hwazgwia

hwazgwia5#

在C/C++中,变量作用域由 * 大括号 * 限制,因此以下代码对编译器有效:

int k()
{ 
    int k=0;
    {  
        int k=1;
        {
           int k=2;               
        }    
    } 
    return k; // guess which k-variable is returned! 
}

相关问题