2008-09-24 2 views
3

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

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

#define count 1 

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

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

ответ

7

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

0

Что вы подразумеваете под «нахождением»?

Линия

#define count 1 

определяет символ «подсчет», который имеет значение 1.

Первый шаг компиляции процесса (называется предварительной обработки) заменит каждое вхождение символа считать с 1, так что если у вас есть:

if (x > count) ... 

будет заменен:

if (x > 1) ... 

Если вы это поняли, вы можете понять, почему «найти счет» бессмысленно.

0

#define является директивой препроцессора, как таковые, он не является «переменным»

1

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

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

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

6

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

Нет

5

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

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

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

+0

Где каламбур ??? – paxdiablo 2008-09-24 14:18:27

+0

Это была ссылка на вопрос, который я только что ответил об использовании «этого» в конструкторе. – 2008-09-24 14:20:29

0

То, что у вас есть, на самом деле не является переменной, это директива препроцессора. Когда вы скомпилируете код, препроцессор выполнит и заменит все строки слова «count» в этом файле на 1.

Возможно, вы спрашиваете, знаю ли я, могу ли я найти, что подсчет указывает на это? Нет. Поскольку связь между именами переменных и значениями не является биекцией, пути назад нет. Рассмотрение

int count = 1; 
int count2 = 1; 

совершенно легально, но что нужно решить?

8

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

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

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

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

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

0

В общем, нет.

Во-первых, #define не является переменной, это макрос препроцессора компилятора.

К моменту завершения основной фазы компилятора имя заменяется значением, а имя «счетчик» не будет существовать нигде в компилируемом коде.

Для переменных невозможно определить имена переменных в коде C во время выполнения. Эта информация не сохраняется. В отличие от языков, таких как Java или C#, C не содержит много метаданных вообще, скомпилируется до языка ассемблера.

0

Директива, начинающаяся с «#», обрабатывается препроцессором, который обычно выполняет замену текста перед передачей кода в «настоящий» компилятор. Таким образом, нет переменной, называемой count, так как все строки «count» в вашем коде магически заменены строкой «1».

Итак, нет, нет способа найти эту «переменную».

0

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

Так что ответ отрицательный.

3

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

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

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

0

Если они смотрят на исходный C код (который они будут в отладчике), то они будут видеть что-то вроде

int i = count; 

в этой точке, они могут искать назад и найти линию

#define count 1 

Если, однако, все, что у них есть, это переменная iDontKnowWhat, и они могут видеть, что это contans 1, нет способа отследить это до «count».

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

0

Это не указатель, это просто замена строки/токена. Препроцессор заменяет все #defines перед компиляцией вашего кода. Большинство компиляторов включают в себя -E или аналогичный аргумент для извлечения предварительно скомпилированного кода, поэтому вы можете видеть, как выглядит код после того, как все #directives обработаны.

Более конкретно к вашему вопросу нет способа сказать, что токен заменяется кодом. Ваш код не может даже сказать разницу между (count == 1) и (1 == 1).

Если вы действительно хотите это сделать, возможно, это будет возможно с использованием анализа текста исходного файла, скажем, с помощью инструмента diff.

2

Один трюк, используемый в 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 
0

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

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

против

enum { 
    ZERO, 
    ONE, 
    TWO 
}; 

Учитывая код:

x = TWO; 

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

1

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

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

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

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

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

2

#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) { 
    ... 
} 
Смежные вопросы