Поиск имени переменной в C

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

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

#define count 1

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
670
18
Перейти к ответу Данный вопрос помечен как решенный

Ответы 18

Что вы имеете в виду под словом «поиск»?

Линия

#define count 1

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

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

if (x > count) ...

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

if (x > 1) ...

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

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

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

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

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

Can that person find the variable name "count" using the 1 that is inside it?

Нет

Ответ принят как подходящий

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

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

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

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

Это была ссылка на вопрос, на который я только что отвечал, об использовании this в конструкторе.

Henry B 24.09.2008 18:20

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

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

int count = 1;
int count2 = 1;

совершенно законно, но на что я должен решиться?

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

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

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

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

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

В общем нет.

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

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

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

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

Так что нет никакой возможности найти эту «переменную».

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

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

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

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

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

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

int i = count;

в этот момент они могут поискать и найти строку

#define count 1

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

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

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

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

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

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

Возможно, в нем нет прямого ответа на вопрос, но я нашел его полезным, ясным и полезным для меня.

ViennaMike 02.01.2012 07:40

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

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

против

enum {
  ZERO,
  ONE,
  TWO
};

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

x = TWO;

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

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

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

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

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

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

#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) {
   ...
}

Другие вопросы по теме