昨晚我被问到C中的一个问题我不知道答案,因为自从大学以来我没有使用过C,所以我想也许我可以在这里找到答案而不是忘记它。

如果某人有如下定义:

#define count 1

该人是否可以使用其中的1找到变量名 count

我不这么认为,因为我认为伯爵会指向1,但不知道1如何能指回计数。

有帮助吗?

解决方案

简单的答案是不,他们不能。这样的#Defines由预处理器处理,它们只指向一个方向。当然另一个问题是即使编译器也不会知道 - 作为“1”。可以指向任何东西 - 多个变量可以同时具有相同的值。

其他提示

在@Cade Roux的答案的基础上,如果您使用预处理器#define将值与符号相关联,则在预处理器运行后代码将不会对该符号进行任何引用:

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

预处理器运行后:

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

正如其他人所指出的,出于上述原因,这基本上意味着“不”。

  
    

该人是否可以找到变量名称“count”使用里面的1?

  

没有

因为我确信比我更有说服力和精通的人会指出#define'd事件没有编译到源代码中,你所拥有的是一个预处理器宏,它将通过源代码并更改所有实例'count'找到'1'。

然而,为了更好地了解您被问到的问题,因为C是一种编译语言,直到机器代码,您将永远不会使用Java或C#等语言进行反思和内省。编译后所有命名都会丢失,除非你有一个围绕源/编译器构建的框架来做一些漂亮的东西。

希望这个有所帮助。 (原谅双关语)

不幸的是,这是不可能的。

#define 语句是预处理程序的指令, count 的所有实例都替换为 1 。在运行时,没有与 count 关联的内存位置,因此这种努力显然是徒劳的。

即使您使用变量,编译后也不会有程序中使用的原始标识符的残余。这通常只能在动态语言中使用。

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

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

C define是一个预处理器指令,而不是变量。在编译之前,预处理器将通过您的C文件并替换您在其中编写计数的位置。查看混淆的C竞赛条目,了解这个和其他预处理器指令的一些特别开明的用法。

重点是没有'计数'指向'1'值。它只是一个简单/查找替换操作,代码甚至真正编译之前发生。

我会让这个可编辑的人真正知道C要纠正。

count 不是变量。它没有分配存储空间,符号表中没有条目。在将源代码传递给编译器之前,它是一个被预处理器替换的宏。

如果您没有提出正确的问题,可以使用宏来获取名称:

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

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

运算符将宏参数转换为字符串文字。

#define 是一个预处理器指令,因此它不是“变量”

你所拥有的实际上不是一个变量,它是一个预处理器指令。编译代码时,预处理器将通过并用1替换该文件中“count”一词的所有实例。

您可能会问我是否知道1我可以找到计数点吗?不可以。因为变量名称和值之间的关系不是双射,所以无法回头。考虑

int count = 1;
int count2 = 1;

完全合法,但1应该解决什么?

一般来说,没有。

首先,#define不是变量,它是编译器预处理器宏。

当编译器的主要阶段开始工作时,名称已被替换为值,名称为“count”。将不会存在于已编译的代码中的任何位置。

对于变量,在运行时无法在C代码中找到变量名。这些信息没有保留。与Java或C#等语言不同,在编译汇编语言时,C根本不会保留太多元数据。

以“#”开头的指令由预处理器处理,通常在将代码传递给“真实”编译器之前进行文本替换。因此,没有称为计数的变量,就像所有“计数”一样。您的代码中的字符串被神奇地替换为“1”。字符串。

所以,不,没办法找到那个“变量”。

如果是宏,则对其进行预处理,然后编译生成的输出。因此,绝对无法找到该名称,因为在预处理器完成其工作后,生成的文件将在文件的任何位置包含“1”而不是“count”。

所以答案是否定的。

如果他们正在查看C源代码(他们将在调试器中),那么他们会看到类似

的内容
int i = count;

此时,他们可以搜索并找到该行

#define count 1

但是,如果他们拥有的只是变量iDontKnowWhat,并且他们可以看到它是1,那么就没有办法追溯到'count'。

为什么呢?因为#define是在预处理器时间进行评估的,甚至在编译之前就会进行评估(尽管对于几乎所有人来说,它都可以被视为编译的第一阶段)。因此,源代码是唯一有关于'count'的信息,比如知道它曾经存在过。在编译器查看时,对'count'的每个引用都被数字'1'替换。

它不是指针,它只是一个字符串/标记替换。在您的代码编译之前,预处理器会替换所有#defines。大多数编译器都包含一个-E或类似的参数来发出预编译的代码,因此您可以在处理完所有#directives后看到代码的样子。

更直接的问题是,没有办法告诉代码中的令牌被替换。你的代码甚至无法区分(count == 1)和(1 == 1)。

如果你真的想这样做,可以使用源文件文本分析,比如使用diff工具。

“发现”是什么意思?

该行

#define count 1

定义符号“count”。有价值1。

编译过程的第一步(称为预处理)将用1替换符号计数的每个出现,这样如果你有:

if (x > count) ...

它将被替换为:

if (x > 1) ...

如果你这样做,你可能会看到为什么“寻找计数”没有意义。

提问的人(这是一个面试问题吗?)可能试图让你区分使用#define常数和枚举。例如:

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

VS

enum {
  ZERO,
  ONE,
  TWO
};

鉴于代码:

x = TWO;

如果使用枚举而不是#defines,一些调试器将能够显示值TWO的符号形式,而不仅仅是数字值2.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top