如何使用变量作为(部分)变量名?(C)

如何使用变量作为(部分)变量名?(C),c,C,假设我有这个功能 void do_work (foo?); 那个?表示将作为变量值的0或1 int bar = 0; 还有一些变量 int foo0 = 0; int foo1 = 0; 我试图将一个变量的值注入另一个变量的名称中,以便函数根据前面的逻辑获取任一变量的全名 我该怎么做 在这种情况下,我不担心实践的好坏。使用数组或指针。您可以使用,例如foo[ind]来访问它。使用数组或指针。您可以使用,例如foo[ind]来访问它。使用数组: int foo[2] = {0, 0}

假设我有这个功能

 void do_work (foo?);
那个?表示将作为变量值的0或1

 int bar = 0;
还有一些变量

 int foo0 = 0;
 int foo1 = 0;
我试图将一个变量的值注入另一个变量的名称中,以便函数根据前面的逻辑获取任一变量的全名

我该怎么做


在这种情况下,我不担心实践的好坏。

使用数组或指针。您可以使用,例如foo[ind]来访问它。

使用数组或指针。您可以使用,例如foo[ind]来访问它。

使用数组:

int foo[2] = {0, 0};
然后你就可以打字了

do_work(foo[bar]);
使用数组:

int foo[2] = {0, 0};
然后你就可以打字了

do_work(foo[bar]);
为了保留原始的foo1和foo2变量,您可以设置一个带有指向这些位置的指针的数组,并通过数组中的指针读/写变量

…然后您可以使用以下命令调用函数:

do_work(*fooArray[bar]);
为了保留原始的foo1和foo2变量,您可以设置一个带有指向这些位置的指针的数组,并通过数组中的指针读/写变量

…然后您可以使用以下命令调用函数:

do_work(*fooArray[bar]);

数组被设计用来保存同质数据类型的值,没有人会将foo0、foo1用于此类需求

数组被设计用来保存同质数据类型的值,没有人会将foo0、foo1用于此类需求

因为你说你不关心好的或坏的实践,您可以在不引入任何新变量的情况下实现所需的行为:

if (bar == 0)
    do_work(foo0);
else if (bar == 1)
    do_work(foo1);
else
    puts("Uh oh, unexpected bar value!");

既然你说你不关心好的或坏的实践,你可以在不引入任何新变量的情况下实现你想要的行为:

if (bar == 0)
    do_work(foo0);
else if (bar == 1)
    do_work(foo1);
else
    puts("Uh oh, unexpected bar value!");

C的工作方式可能与您的想法不同。您不能像在其他语言中使用的那样,在运行时动态引用变量的名称

也就是说,函数参数的名称是不相关的

void do_work(int arg)
{
} 
您不必将arg的名称与foo0或foo1匹配。现在,您可以将任一变量传递到函数中:

int foo0, foo1;

if (some_condition)
  do_work(foo0);
else
  do_work(foo1);
现在,函数do_work将处理传递的变量的副本。因此,如果在函数内部更改变量的值,那么在函数外部它仍然保持不变。您可以通过返回新值来更改该值:

int do_work(int arg)
{
  return arg + 1;
}

foo0 = do_work(foo0);
最后,听起来您想要使用数组:

int foo[2]; // create two ints: foo[0] and foo[1]

do_work(foo[0]);

int i = 1;
do_work(foo[i]);

C的工作方式可能与您的想法不同。您不能像在其他语言中使用的那样,在运行时动态引用变量的名称

也就是说,函数参数的名称是不相关的

void do_work(int arg)
{
} 
您不必将arg的名称与foo0或foo1匹配。现在,您可以将任一变量传递到函数中:

int foo0, foo1;

if (some_condition)
  do_work(foo0);
else
  do_work(foo1);
现在,函数do_work将处理传递的变量的副本。因此,如果在函数内部更改变量的值,那么在函数外部它仍然保持不变。您可以通过返回新值来更改该值:

int do_work(int arg)
{
  return arg + 1;
}

foo0 = do_work(foo0);
最后,听起来您想要使用数组:

int foo[2]; // create two ints: foo[0] and foo[1]

do_work(foo[0]);

int i = 1;
do_work(foo[i]);

根据@dreamlax的特殊要求:

1将这些变量声明为

__declspec( dllexport ) static int foo1;
__declspec( dllexport ) static int foo2;
2使用HANDLE this_module=GetModuleHandleNULL;获取当前模块

3获取所需变量的名称:

char vname[100];
sprintf(vname, "foo%d", bar);
4.找到它:

int* fooX = (int*)GetProcAddress(this_module, vname);
5,最后,您可以使用它:

  do_work(fooX);  // or *fooX, as you like

根据@dreamlax的特殊要求:

1将这些变量声明为

__declspec( dllexport ) static int foo1;
__declspec( dllexport ) static int foo2;
2使用HANDLE this_module=GetModuleHandleNULL;获取当前模块

3获取所需变量的名称:

char vname[100];
sprintf(vname, "foo%d", bar);
4.找到它:

int* fooX = (int*)GetProcAddress(this_module, vname);
5,最后,您可以使用它:

  do_work(fooX);  // or *fooX, as you like

这里有个坏主意:

#define foo0 foo[0]
#define foo1 foo[1]
#define foobar foo[bar]

int foo[2];
int bar;

这里有个坏主意:

#define foo0 foo[0]
#define foo1 foo[1]
#define foobar foo[bar]

int foo[2];
int bar;

你知道在运行时变量名是不存在的吗?哈哈,你可能会这么认为obvious@ruslik:这完全取决于悬挂机构。共享库中的全局变量可以在运行时按名称查找。您是否知道这些变量名称在运行时不存在?哈哈,您可能会这样认为obvious@ruslik:这完全取决于悬挂机构。共享库中的全局变量可以在运行时按名称查找。平台相关解决方案。你在用指针工作,你不能用一些简单的散列吗?嗯,这只是一个概念证明。-1用于教新手如何做他想做的蠢事。+1。这是一个非常错误的做法:使用静态绑定语言,并使用其平台对符号进行后期绑定的能力,在运行时计算符号名称。虽然我们都同意在这种情况下这样做是错误的,但这是解决一些问题的正确答案。例如,Lua解释器在从DLL或.so文件加载用C编写的模块时执行此操作。模块的入口点的名称类似于luaopen_foo,其中foo是模块的名称。只有在运行时执行require foo函数调用时才知道该名称。这永远不是正确的做法。它始终是特定于平台的,不适用于没有您的任意平台
t为平台发明自己的动态链接系统,在最坏的情况下,需要编写一个C编译器/链接器来输出字节码和一个字节码解释器。即使不是针对这些问题,对另一个潜在有趣的高级使用问题的回答也不属于对新手问题的回答。依赖平台的解决方案。你在用指针工作,你不能用一些简单的散列吗?嗯,这只是一个概念证明。-1用于教新手如何做他想做的蠢事。+1。这是一个非常错误的做法:使用静态绑定语言,并使用其平台对符号进行后期绑定的能力,在运行时计算符号名称。虽然我们都同意在这种情况下这样做是错误的,但这是解决一些问题的正确答案。例如,Lua解释器在从DLL或.so文件加载用C编写的模块时执行此操作。模块的入口点的名称类似于luaopen_foo,其中foo是模块的名称。只有在运行时执行require foo函数调用时才知道该名称。这永远不是正确的做法。它始终是特定于平台的,如果不为平台创建自己的动态链接系统,它就无法适应任意平台。在最坏的情况下,它需要编写一个C编译器/链接器来输出字节码和一个字节码解释器。即使不是针对这些问题,对另一个潜在有趣的高级使用问题的回答也不属于对新手问题的回答。