Нахождение имени переменной в C - PullRequest
3 голосов
/ 24 сентября 2008

Вчера вечером мне задали вопрос на языке C, и я не знал ответа, так как с тех пор, как поступил в колледж, я почти не использовал C, поэтому подумал, что, возможно, я смогу найти ответ здесь, а не просто забыть об этом.

Если у человека есть определение, например:

#define count 1

Может ли этот человек найти имя переменной count, используя 1, находящуюся внутри нее?

Я так не думал, так как думал, что счет будет указывать на 1, но не вижу, как 1 может указывать на счет.

Ответы [ 18 ]

8 голосов
/ 24 сентября 2008

Основываясь на ответе @Cade Roux, если вы используете препроцессор #define для связывания значения с символом, код не будет иметь никакой ссылки на символ после запуска препроцессора:

#define COUNT (1)
...
int myVar = COUNT;
...

После запуска препроцессора:

...
int myVar = (1);
...

Итак, как уже отмечали другие, это в основном означает «нет» по вышеуказанной причине.

7 голосов
/ 24 сентября 2008

Простой ответ: нет, они не могут. # С такими определениями занимается препроцессор, и они указывают только в одном направлении. Конечно, другая проблема заключается в том, что даже компилятор не будет знать - поскольку «1» может указывать на что угодно - несколько переменных могут иметь одно и то же значение одновременно.

6 голосов
/ 24 сентября 2008

Может ли этот человек найти имя переменной "count", используя 1, находящуюся внутри нее?

нет

Нет

5 голосов
/ 24 сентября 2008

Поскольку я уверен, что кто-то более красноречивый и опытный, чем я, укажет # define'd вещи не скомпилированы в источник, у вас есть макрос препроцессора, который будет проходить через источник и изменять весь экземпляр 'count' находит с '1'.

Однако, чтобы пролить больше света на вопрос, который вам задавали, поскольку C - это скомпилированный язык вплоть до машинного кода, вы никогда не будете иметь отражения и самоанализа, которые есть у вас с таким языком, как Java или C #. Все наименования теряются после компиляции, если у вас нет фреймворка, построенного вокруг вашего исходного кода / компилятора, чтобы сделать некоторые изящные вещи.

Надежда это помогает. (извините за каламбур)

3 голосов
/ 24 сентября 2008

К сожалению, это невозможно.

#define операторы являются инструкциями для препроцессора, все экземпляры count заменены на 1. Во время выполнения нет места в памяти, связанного с count, поэтому усилия явно бесполезны.

Даже если вы используете переменные, после компиляции не останется остатков исходных идентификаторов, используемых в программе. Обычно это возможно только в динамических языках.

2 голосов
/ 24 сентября 2008

Один прием, используемый в C, использует синтаксис # в макросах для получения строкового литерала параметра макроса.

#define displayInt(val) printf("%s: %d\n",#val,val)
#define displayFloat(val) printf("%s: %d\n",#val,val)
#define displayString(val) printf("%s: %s\n",#val,val)

int main(){
  int foo=123;
  float bar=456.789;
  char thud[]="this is a string";

  displayInt(foo);
  displayFloat(bar);
  displayString(thud);

  return 0;
}

Вывод должен выглядеть примерно так:

foo: 123
bar: 456.789
thud: this is a string
2 голосов
/ 24 сентября 2008

#define count 1 - очень плохая идея, потому что она не позволяет вам называть любые переменные или структурные поля count.

Например:

void copyString(char* dst, const char* src, size_t count) {
   ...
}

Ваш макрос count приведет к замене имени переменной на 1, предотвращая компиляцию этой функции:

void copyString(char* dst, const char* src, size_t 1) {
   ...
}
1 голос
/ 24 сентября 2008

C определяет директиву препроцессора, а не переменную. Препроцессор перед компиляцией проверит ваш C-файл и заменит то, что вы записали, на то, что вы определили. Посмотрите на запутанные записи конкурса C для некоторых особенно просвещенных способов использования этой и других директив препроцессора.

Дело в том, что нет «счетчика», указывающего на значение «1». Это просто простая операция поиска / замены, которая происходит до , код даже действительно скомпилирован.

Я оставлю это редактируемым для того, кто действительно знает C, чтобы исправить.

1 голос
/ 24 сентября 2008

count не является переменной. У него нет выделенной памяти и нет записи в таблице символов. Это макрос, который заменяется препроцессором перед передачей исходного кода компилятору.

Если вы не задаете совершенно правильный вопрос, есть способ получить имя с помощью макросов:

#define SHOW(sym) (printf(#sym " = %d\n", sym))
#define count 1

SHOW(count); // prints "count = 1"

Оператор # преобразует аргумент макроса в строковый литерал.

0 голосов
/ 24 сентября 2008

Человек, задающий вопрос (это был вопрос на собеседовании?), Возможно, пытался заставить вас провести различие между использованием #define constants и enums. Например:

#define ZERO 0
#define ONE 1
#define TWO 2

против

enum {
  ZERO,
  ONE,
  TWO
};

С учетом кода:

x = TWO;

Если вы используете перечисления вместо #defines, некоторые отладчики смогут показывать вам символическую форму значения, ДВА, а не только числовое значение 2.

...