1

我想使用一个动态变量,其值在运行时会发生变化。

例如

char * aVar = "ABC";
char * bVar = "DEF";
char * cVar = "XYZ";

char *dVar = NULL;

dVar = foo1();

print dVar;

foo1内部调用foo2,它应该返回变量名(如"aVar""bVar""cVar")。foo1应该根据foo2返回值返回所述变量的值。

要获取变量名,我们可以使用(非标准)宏:

##define GET_VAR(varname) #varname; 

...但是我怎样才能获得命名变量的值?

4

4 回答 4

4

这里的简单答案是这在 C 中是不可能的。

更长的答案是,这需要语言中的自省和动态特性,这通常只在 Python 等脚本语言中看到。即使在那里做这样的事情也不被鼓励。

我建议您重新考虑您正在尝试解决的问题,并检查是否可能没有更好的方法来解决它。也许使用数组、映射或哈希表可能是适合您的替代方法。

于 2012-09-15T07:51:43.983 回答
2

C 不是动态语言——你不能真正做到这一点。为此,您最好使用某种数据结构,例如字典(键值存储,关联数组,无论您如何称呼它)。

好吧,除非……除非你有一个符合 POSIX 的系统并且你喜欢邪恶的动态加载。

#include <dlfcn.h>
#include <stdio.h>

int globalVarOne = 1;
int globalVarTwo = 2;
int globalVarThree = 3;

int getValueOfVariableNamed(const char *name)
{
    void *ptr = dlsym(RTLD_SELF, name);
    return *(int *)ptr;
}

int main()
{
    printf("globalVarOne = %d\n", getValueOfVariableNamed("globalVarOne"));
    // etc.
}

印刷:

globalVarOne = 1

请注意,这只适用于全局变量。

编辑:正如@oldrinb 指出的那样,如果你void *ptr = GetProcAddress(GetModuleHandle(NULL), name);void *ptr = dlsym(RTLD_SELF, name);.

于 2012-09-15T07:55:06.190 回答
1

您不能直接在 C 中执行此操作。

但是,您可以执行以下操作:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct Binding
{
  int* pIntVar;
  const char* IntVarName;
  struct Binding* pNext;
} Binding;

Binding* Bindings = NULL;

void BindVar(const char* IntVarName, int* pIntVar)
{
  Binding* b;
  if ((b = malloc(sizeof(Binding))) != NULL)
  {
    b->IntVarName = IntVarName;
    b->pIntVar = pIntVar;
    b->pNext = NULL;
    if (Bindings == NULL)
    {
      Bindings = b;
    }
    else
    {
      Binding* bs = Bindings;
      while (bs->pNext != NULL)
      {
        bs = bs->pNext;
      }
      bs->pNext = b;
    }
  }
  else
  {
    fprintf(stderr, "malloc() failed\n");
    exit(-1);
  }
}

int* GetVarPtr(const char* IntVarName)
{
  Binding* bs = Bindings;
  while (bs != NULL)
  {
    if (!strcmp(bs->IntVarName, IntVarName))
    {
      return bs->pIntVar;
    }
    bs = bs->pNext;
  }
  fprintf(stderr, "variable \"%s\" not bound yet!\n", IntVarName);
  exit(-1);
}

int main(void)
{
  int ABC = 111, DEF = 222, XYZ = 333;
  const char* varName = NULL;

  BindVar("ABC", &ABC);
  BindVar("DEF", &DEF);
  BindVar("XYZ", &XYZ);

  printf("variable \"%s\" = %d\n", "ABC", *GetVarPtr("ABC"));
  printf("variable \"%s\" = %d\n", "DEF", *GetVarPtr("DEF"));
  printf("variable \"%s\" = %d\n", "XYZ", *GetVarPtr("XYZ"));

  // Pick a variable randomly by name

  switch (rand() % 3)
  {
  case 0: varName = "ABC"; break;
  case 1: varName = "DEF"; break;
  case 2: varName = "XYZ"; break;
  }

  printf("variable \"%s\" (selected randomly) = %d\n", varName, *GetVarPtr(varName));

  return 0;
}

输出(ideone):

variable "ABC" = 111
variable "DEF" = 222
variable "XYZ" = 333
variable "DEF" (selected randomly) = 222

由于GetVarPtr()返回一个指向变量的指针,你不仅可以获取变量的值,还可以设置它。

您甚至可以将指针隐藏在宏后面:

#define VARIABLE(NAME) (*GetVarPtr(NAME))

通过这种方式,您可以执行以下操作(ideone):

VARIABLE("ABC") = 1;
VARIABLE("DEF") = 2;
VARIABLE("XYZ") = 3;

printf("variable \"%s\" = %d\n", "ABC", VARIABLE("ABC"));
printf("variable \"%s\" = %d\n", "DEF", VARIABLE("DEF"));
printf("variable \"%s\" = %d\n", "XYZ", VARIABLE("XYZ"));
于 2012-09-15T08:47:52.450 回答
0

您不能在运行时使用宏。

你应该使用一个数组。

于 2012-09-15T07:48:48.867 回答