昨晚我被问到C中的一个问题我不知道答案,因为自从大学以来我没有使用过C,所以我想也许我可以在这里找到答案而不是忘记它。
如果某人有如下定义:
#define count 1
该人是否可以使用其中的1找到变量名count
?
我不这么认为,因为我认为计数会指向1,但不会看到1如何指回计数。
答案 0 :(得分:8)
在@Cade Roux的答案的基础上,如果您使用预处理器#define将值与符号相关联,则在预处理器运行后代码将不会对该符号进行任何引用:
#define COUNT (1)
...
int myVar = COUNT;
...
预处理器运行后:
...
int myVar = (1);
...
正如其他人所说,由于上述原因,这基本上意味着“不”。
答案 1 :(得分:7)
简单的答案是不,他们不能。这样的#Defines由预处理器处理,它们只指向一个方向。当然另一个问题是即使编译器也不会知道 - 因为“1”可以指向任何东西 - 多个变量可以同时具有相同的值。
答案 2 :(得分:6)
该人是否可以使用其中的1找到变量名“count”?
没有
答案 3 :(得分:5)
因为我确信比我更有说服力和精通的人会指出#define'd事件没有编译到源代码中,你所拥有的是一个预处理器宏,它将通过源代码并更改所有实例'count'找到'1'。
然而,为了更好地了解您被问到的问题,因为C是一种编译语言,直到机器代码,您将永远不会使用Java或C#等语言进行反思和内省。编译后所有命名都会丢失,除非你有一个围绕源/编译器构建的框架来做一些漂亮的东西。
希望这个有所帮助。 (原谅双关语)
答案 4 :(得分:3)
不幸的是,这是不可能的。
#define
语句是预处理程序的说明,count
的所有实例都替换为1
。在运行时,没有与count
关联的内存位置,因此这种努力显然是徒劳的。
即使您使用变量,编译后也不会有程序中使用的原始标识符的残余。这通常只能在动态语言中使用。
答案 5 :(得分: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) {
...
}
答案 6 :(得分: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
答案 7 :(得分:1)
C define是一个预处理器指令,而不是变量。在编译之前,预处理器将通过您的C文件并替换您在其中编写计数的位置。查看混淆的C竞赛条目,了解这个和其他预处理器指令的一些特别开明的用法。
重点是没有'计数'指向'1'值。它只是一个简单/查找替换操作,在代码甚至真正编译之前发生。
我会让这个可编辑的人真正知道C要纠正。
答案 8 :(得分:1)
count
不是变量。它没有分配存储空间,符号表中没有条目。在将源代码传递给编译器之前,它是一个被预处理器替换的宏。
如果您没有提出正确的问题,可以使用宏来获取名称:
#define SHOW(sym) (printf(#sym " = %d\n", sym))
#define count 1
SHOW(count); // prints "count = 1"
#
运算符将宏参数转换为字符串文字。
答案 9 :(得分:0)
以“#”开头的指令由预处理器处理,预处理器通常在将代码传递给“真实”编译器之前进行文本替换。因此,没有名为count的变量,就好像代码中的所有“count”字符串被神奇地替换为“1”字符串一样。
所以,不,没办法找到那个“变量”。
答案 10 :(得分:0)
提问的人(这是一个面试问题吗?)可能试图让你区分使用#define常数和枚举。例如:
#define ZERO 0
#define ONE 1
#define TWO 2
VS
enum {
ZERO,
ONE,
TWO
};
鉴于代码:
x = TWO;
如果使用枚举而不是#defines,一些调试器将能够显示值TWO的符号形式,而不仅仅是数字值2.
答案 11 :(得分:0)
它不是指针,它只是一个字符串/标记替换。在您的代码编译之前,预处理器会替换所有#defines。大多数编译器都包含一个-E或类似的参数来发出预编译的代码,因此您可以看到在处理完所有#directives之后代码的样子。
更直接的问题是,没有办法告诉代码中的令牌被替换。你的代码甚至无法区分(count == 1)和(1 == 1)。
如果你真的想这样做,可以使用源文件文本分析,比如使用diff工具。
答案 12 :(得分:0)
如果他们正在查看C源代码(他们将在调试器中),那么他们会看到类似
的内容int i = count;
此时,他们可以搜索并找到该行
#define count 1
但是,如果他们拥有的只是变量iDontKnowWhat,并且他们可以看到它是1,那么就没有办法追溯到'count'。
为什么呢?因为#define是在预处理器时间进行评估的,甚至在编译之前就会进行评估(尽管对于几乎所有人来说,它都可以被视为编译的第一阶段)。因此,源代码是唯一有关于'count'的信息,比如知道它曾经存在过。在编译器查看时,对'count'的每个引用都被数字'1'替换。
答案 13 :(得分:0)
如果是宏,则对其进行预处理,然后编译生成的输出。因此,绝对无法找到该名称,因为在预处理器完成其工作后,生成的文件将在文件的任何位置包含“1”而不是“count”。
所以答案是否定的。
答案 14 :(得分:0)
“找到”是什么意思?
该行
#define count 1
定义符号“count”,其值为1.
编译过程的第一步(称为预处理)将用1替换符号计数的每个出现,这样如果你有:
if (x > count) ...
它将被替换为:
if (x > 1) ...
如果你明白这一点,你可能会发现为什么“找到计数”毫无意义。
答案 15 :(得分:0)
一般来说,没有。
首先,#define不是变量,它是编译器预处理器宏。
当编译器的主要阶段开始工作时,名称已被替换为值,并且名称“count”将不会存在于编译的代码中的任何位置。
对于变量,在运行时无法在C代码中找到变量名。这些信息没有保留。与Java或C#等语言不同,在编译汇编语言时,C根本不会保留太多元数据。
答案 16 :(得分:0)
你所拥有的实际上不是一个变量,它是一个预处理器指令。编译代码时,预处理器将通过并用1替换该文件中“count”一词的所有实例。
您可能会问我是否知道1我可以找到计数点吗?不可以。因为变量名称和值之间的关系不是双射,所以无法回头。考虑
int count = 1;
int count2 = 1;
完全合法,但1应该解决什么?
答案 17 :(得分:0)
#define
是一个预处理器指令,因此它不是“变量”