【问题标题】:How to return a variable name and assign the value of the variable returned in c如何返回一个变量名并为c中返回的变量赋值
【发布时间】:2012-09-08 06:29:24
【问题描述】:

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

例如

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; 

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

【问题讨论】:

  • 现在你到底为什么要在 C 中这样做?
  • @oldrinb - 我打算按照这个思路说点什么。为什么不只返回适当的指针(即使有全局变量是个坏主意)
  • 或者将输出参数分别传递给函数 foo1() 和 foo2(),它们只是在完成处理后将值放入参数中
  • @oldrinb:就我个人而言,即使在支持它的语言中,我似乎也没有发现自己这样做。大多数允许它的语言似乎都有易于使用的关联容器。并非巧合;-)

标签: c variables return assign


【解决方案1】:

您不能在运行时使用宏。

你应该使用一个数组。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 虽然不建议这样做,但您可以进行动态加载 - 请参阅我的答案。
    • 这当然是一种有趣的方法。我怀疑它是否非常便携,如果编译器或链接器进行一些意想不到的优化,它可能会中断。仍然 - 提出这个的奖励积分:)
    • 它应该可以跨 POSIC 移植。
    【解决方案3】:

    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);,您也可以在Windows 上执行此操作。

    【讨论】:

    • 等效于 Windows:GetProcAddress(GetModuleHandle(NULL), name)
    • 这个dlsym() 很方便。
    【解决方案4】:

    你不能直接在 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"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      • 1970-01-01
      • 2021-08-13
      • 1970-01-01
      • 2017-02-25
      • 1970-01-01
      • 2017-11-18
      相关资源
      最近更新 更多