C++ 从内部作用域访问阴影变量

C++ 从内部作用域访问阴影变量,c++,c++14,c++17,C++,C++14,C++17,我的代码: int num = 1; // global scope int main(){ int num = 2; // local scope 1 { // local scope 2 int num = 3; { // local scope 3

我的代码:

int num = 1; // global scope
int main(){
      int num = 2;                         // local scope 1
           {                              // local scope 2
             int num = 3;
              {                          // local scope 3
                  int num = 4;
                   std::cout<<num<<"\n";            // printing local scope 3
                   std::cout<<::num<<"\n";         // printing global scop 
                   // but here how to print local scope 1, 2 variables
               }
           }
int num=1;//全球范围
int main(){
int num=2;//本地作用域1
{//局部作用域2
int num=3;
{//局部范围3
int num=4;

std::cout您不能简单地实现这一点,因为内部变量只是掩盖了外部范围变量

如果内部块声明的变量与外部块声明的变量同名,则外部块变量的可见性在内部块声明的点处结束

但是,如果您仍然需要实现这一点,您可以采取措施将变量值存储在堆栈中,以保存每个作用域的变量值。这类似于在函数调用期间所做的操作(只是一个仅存储所需变量的修订版本)


我仍然建议您为变量使用单独的名称,因为这会降低代码的可读性。

这可能有点像黑客任务。 我花了一些时间处理指针等问题,并找到了一些解决方案:

#include <iostream>

int num = 0;
int main()
{
    int *addressNumGlobal = &num;
   std::cout << "Address num global: " << addressNumGlobal << endl; 
   int num = 1;
   int *addressNum1 = &num;
    std::cout << "Address of num 1: " << addressNum1 << std::endl;
   {
       int num = 2;
       int *addressNum2 = &num;
       std::cout << "Address of num 2: " << addressNum2 << std::endl;
       {
           int num = 3;
           int *addressNum3 = &num;
            std::cout << "Address of num 3: " << addressNum3 << std::endl;
           char *myNum = (char*)(&num);
           int *addressNum2 = (int*)(myNum + sizeof(int));
            std::cout << "Calculated Address of num 2: " << addressNum2 << std::endl;
           int num2Value = *addressNum2;
           std::cout << num2Value << std::endl;
           std::cout << ::num << std::endl;
       }
   }
   return 0;
}
当然,地址会在不同的运行中更改,但会获得对num(2)的访问权限:)


所以num(1)、num(2)、num(3)存储在一个“行”中。它可能会在另一个编译器上失败。但无论如何,这是一个很好的想法:)

不完全清楚您到底想要什么。您使用了递归这个词,但是 我们没有使用递归

但是,我认为您所描述和想要的适合递归函数。 也许像下面这样的事情你想怎么做

#include <iostream>

void printnum(int num, int max)
{
    if (num < max)
        printnum(num+1, max);
    
    std::cout<<num<<"\n";
}
    
int main(){
  printnum(1, 3);
  return 0;
}
#包括
void printnum(int num,int max)
{
如果(数值<最大值)
printnum(num+1,最大值);

std::cout有趣的问题,关于这一点(在生产代码中不要这样做),lambda可以在没有
()
的情况下声明,通过
操作符()
调用,并且从不分配:

#include <iostream>

int main() {  

    int num = 10;
    [num_ = num] {
      int num = 11;
      std::cout << "num " << num << "\n";
      std::cout << "outer_num " << num_ << "\n";
    }(); 

}
#包括
int main(){
int num=10;
[数值=数值]{
int num=11;

std::cout仅在您的范围内使用:

int num = 1; // global scope

int main() {

    int num = 2;                        
    {                             
        int num = 3;
        {                          
            int num = 4;
            std::cout << num << '\n';                       
           
        }
        std::cout << num << '\n';          
    }
    std::cout << num << '\n' << ::num;          
    
    return 0;
}
int num=1;//全局范围
int main(){
int num=2;
{                             
int num=3;
{                          
int num=4;
正如用户所指出的,您不能直接这样做。然而,间接地有一个解决方法,但是它需要使用一个容器

#include <iostream>
#include <vector>

int num = 1;

int main() {
    std::vector<int> results;
    results.push_back(num);
    int num = 2;
    results.push_back(num);
    {
        int num = 3;
        results.push_back(num);
        {
            int num = 4;
            results.push_back(num);
            for (auto& v : results)
                std::cout << v << " ";
            std::cout << '\n';
        }
    }
    return 0;
}

这是根本不可能的,因为你隐藏了scope1,2
num
s,并且它们不能被任何namesapce限定。你需要重命名它们才能进入scope3。为什么不把这些变量推到堆栈上,并在每个作用域内自动管理堆栈呢?对变量使用相同的名称会导致变量隐藏这通常是一个坏主意,因为它会降低可读性和可维护性。这表明,您应该更改命名方案,或者拆分函数。使用递归函数,让每个函数在展开时打印num?您希望在什么时候访问什么范围?您能举一个更好的示例吗?
#include <iostream>
#include <vector>

int num = 1;

int main() {
    std::vector<int> results;
    results.push_back(num);
    int num = 2;
    results.push_back(num);
    {
        int num = 3;
        results.push_back(num);
        {
            int num = 4;
            results.push_back(num);
            for (auto& v : results)
                std::cout << v << " ";
            std::cout << '\n';
        }
    }
    return 0;
}
1 2 3 4