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



我的代码:

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
}
}

伙计们,在我的代码中有嵌套的作用域,我想打印所有具有相同名称的变量,包括阴影变量,来自";局部范围3";。然而,我可以打印全局和本地作用域3的num值,但我不知道访问本地作用域1和2的num值的语法。

不能简单地实现这一点,因为内部变量只会盖过外部范围变量。

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

但是,如果您仍然需要实现这一点,您可以将变量值存储在一个堆栈中,该堆栈按作用域保存变量值。这类似于函数调用过程中所做的操作(只是一个只存储所需变量的修订版本(。

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

只在您的作用域中使用:

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;
}

正如用户jasmeet所指出的,您根本无法直接做到这一点。然而,间接地有一个解决方法,但它需要使用容器。。。

#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

有趣的问题是,这个(不要在生产代码中这样做(,lambdas可以在没有()的情况下声明,通过operator ()调用,并且永远不会分配:

#include <iostream>
int main() {  
int num = 10;
[num_ = num] {
int num = 11;
std::cout << "num " << num << "n";
std::cout << "outer_num " << num_ << "n";
}(); 
}

https://godbolt.org/z/jbhYTf

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

然而,我认为您正在描述和想要的内容适合递归函数。也许下面这样的东西能满足你的需求?

#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;
}

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

#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;
}

我得到以下输出:

Address num global: 0x601174
Address of num 1: 0x7ffc8db08b68
Address of num 2: 0x7ffc8db08b64
Address of num 3: 0x7ffc8db08b60
Calculated Address of num 2: 0x7ffc8db08b64
2
0

当然,地址在不同的运行中变化,但可以访问num(2(:(

因此num(1(、num(2(、num;行";。它可能会在另一个编译器上失败。但无论如何,这是一个很好的想法:(

最新更新