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 に答える