我们说我有一个变量:
int fish5 = 7;
我可以通过连接术语" fish"来访问fish5。和" 5"不知何故?
理想的解决方案看起来像这样:
printf("I am displaying the number seven: %i", fish + 5);
答案 0 :(得分:4)
不,不完全是你想要的。但在您的示例中,您可以使用数组(仅当您要将变量名称与数字连接时才有效):
int fish[6] = {0};
fish[5] = 7;
printf("I am displaying the number seven: %i", fish[5]);
另请参阅here以获取对C ++中的数组的引用。
另一种解决方案是使用std::map
代替,就像Thrustmaster在评论中指出的那样。
然后你可以这样写:
#include <map>
#include <string>
int main(int argc, char* argv[]){
std::map<std::string, int> map;
map.insert(std::make_pair("fish5", 7));
printf("I am displaying the number seven: %d", map[std::string("fish") + std::to_string(5)]);
return 0;
}
有关std::map
的详细信息,请参阅here。
答案 1 :(得分:2)
将解决方案从编译时转换为运行时是不可能的,因为c ++是一种编译语言,而不是解释的语言。变量名称在编译后“失去意义”。它们只是一组带地址的符号。这意味着,在编译后要求fish5
这样的东西没有任何意义。
要实现您想要的功能,您需要以某种方式以编程方式将名称绑定到对象,例如使用映射,将名称存储为键,将对象引用存储为值。这就是python的用法,以及为什么在python中你可以通过代码中的名字实际访问对象。
如果有人想知道为什么例如gdb或崩溃转储是有意义的,那也是出于同样的原因。符号名称必须在编译时保存(嵌入在可执行文件或外部文件中),然后外部工具可以确定某个地址下变量的名称。但是编译后的可执行文件可以很好地处理这些信息。
或者,您需要以更方便的方式记住引用本身,这允许它是可计算的。例如。将其存储在数组中并以fish[5]
进行访问;虽然在此示例中可以在编译时对其进行评估,但您可以在运行时使用相同的方法,使用变量代替5
。
编译时和运行时之间的区别非常重要,因为您可以在编译时使用预处理器实际执行所需的操作,但这只是因为它是编译时。
答案 2 :(得分:2)
您可以使用特定于操作系统的东西,例如(在Posix,例如Linux上)dlsym(3),以便在运行时通过(未提取的)ELF可执行文件内的符号表访问变量。
因此,最好通过名称extern "C"
声明要访问的变量,例如
extern "C" int fish17;
(否则,请考虑编译器特定的name mangling)
还声明一个程序句柄:
void *progdlh;
在main
progdlh = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
if (!progdlh) { fprintf(stderr, "dlopen failure %s\n", dlerror());
exit(EXIT_FAILURE); }
然后,要通过计算名称检索变量,您可以尝试:
char nambuf[32];
snprintf (nambuf, sizeof(nambuf), "%s%d", "fish", 17);
int *pvar = dlsym(progdlh, nambuf);
if (!pvar) { fprintf(stderr, "dlsym %s failure %s\n", nambuf, dlerror());
exit(EXIT_FAILURE); }
printf ("variable %s is %d\n", nambuf, *pvar);
您可能应该将您的程序与-rdynamic
标记(以及-ldl
库)链接
我的回答应该适用于Linux。
答案 3 :(得分:0)
您只能在编译时使用预处理器执行此操作。完整的例子:
#include <cstdio>
#define JOIN(a,b) a##b
int main(void) {
int fish5 = 5;
std::printf("I am displaying the number five: %i", JOIN(fish, 5));
return 0;
}
但是,这是严格的编译时间。如果您尝试JOIN(fish, fish)
,则会获得error: ‘fishfish’ undeclared
,如果您尝试JOIN("fish", fish)
,则会获得error: pasting ""fish"" and "fish" does not give a valid preprocessing token
。
在C ++中,变量名在运行时不存在,因此操作不能在运行时完成,除非一些深度调试信息通过其名称字符串查找变量(就像调试一样)。如果使用字符串对您来说是有效的方法,那么最好只显示从字符串到变量地址的映射。其他答案显示了如何使用std::map
。