例如,我有这个块:
int nFirst, nSecond;
char sInput[10];
printf("Which variable to change to 10?");
scanf("%s", &sInput);
// BAD - inflexible and unmaintainable
if(strcmp(sInput,"nFirst") ==0){
nFirst = 10;
}
else if (strcmp(sInput,"nSecond")==0) {
nSecond =10;
}
有一个很好的方法吗?喜欢将字符串视为变量名吗?
答案 0 :(得分:1)
不,在C中没有“好”的方法。除了支持调试之外,变量名(通常)不会保留在生成的机器代码中。 C没有内置机制将字符串值转换为对同名变量的引用。
您必须手动将变量名称映射到变量。您可以构建一个查找表,将字符串值与相应变量的地址相关联:
struct vn {
char *varname;
void *addr;
Typeinfo t;
};
其中Typeinfo
是一些枚举或其他机制,用于编码变量的类型,为您提供一些效果
int foo;
double bar;
char *blurga;
struct vn varsByName[] = { {"foo", &foo, IntType},
{"bar", &bar, DoubleType},
{"blurga", blurga, CharPtrType} };
我不建议这样做。
答案 1 :(得分:0)
您可以实现类似字典或包含“变量名称”和值的二维数组。然后,这归结为将数组元素设置为新值。
除此之外:C#和其他面向对象的语言将允许通过反射,但由于C本身不是面向对象的,你不能这样做(C ++对此的支持似乎非常有限)。
答案 2 :(得分:0)
另一种依赖于平台的方法是将所有变量放入共享库,然后通过名称访问它们。看看dlsym / dlopen函数。
void* handle = dlopen("mysymbols.so", RTLD_LOCAL | RTLD_LAZY);
int* var = (int*) dlsym(handle, user_typed_name);
*var = 10; /* modify the variable */
答案 3 :(得分:0)
您可以使用宏来执行此操作:
#define MAYBESET(name) if (strcmp(sInput, #name) ==0 ){ name = 10; }
#name
是name
更改为字符串文字的实际值。
答案 4 :(得分:0)
对于少量变量,您的算法应该运行良好。如果有许多变量可以改变,而不仅仅是两个,那么应该考虑另一种算法。在C中使这个漂亮而清晰并不容易。 如果你真的希望这个更快,你可以做哈希表或使用像:
这样的开关/案例int First, Second; // Note that I got rid of your leading n
char sInput[10];
printf("Which variable to change to 10?");
scanf("%s", &sInput);
// BAD - inflexible and unmaintainable
// referring to character array overflow potential, I assume
switch (sInput[0])
{
case 'F':
if (0 == strcmp("irst", sInput+1) )
{
First = 10;
} else
{
// error
}
break;
case 'S':
if (0 == strcmp("econd", sInput+1) )
{
Second = 10;
} else
{
// error
}
break;
default:
// error
break;
}
如果您不喜欢这种外观,那么您可以使用宏(#define
)使其看起来不那么大,但结果会相同。您可以使用的另一个选项是编写一个小程序,输出该程序的源代码,该程序将处理所有重复和繁琐的部分。
另一种方法,如果所有变量属于同一类型,将创建它们的数组并输入它们的索引而不是名称,但是你必须添加代码来检查输入索引超出数组大小的范围。