C中的符号常量(#define语句)

在阅读了K&R的C编程语言之后,我遇到了#define符号常量。 我决定定义……

#define INTEGER_EXAMPLE 2 #define CHAR_EXAMPLE 2 

…所以我的问题是C如何知道我是在定义int还是char类型?

关于这些定义,它没有,扩展的宏没有类型。 处理#define的预处理器只是替换源代码中的文本

当你在某处使用这些定义时,例如

 int i = INTEGER_EXAMPLE; 

这将扩展到

 int i = 2; 

这里将文字2(在此上下文中为int)分配给int。

你也可以这样做:

 char c = INTEGER_EXAMPLE; 

在这里,文字2也是一个int,它被赋值给一个char。 2虽然在char的范围内,所以一切都好。

你甚至可以这样做:

 int INTEGER_EXAMPLE = 2; 

这会扩大到

 int 2 = 2; 

这是无效的C.

#define -d名称没有类型。 他们只是定义文本替换。

编译器看到的是预处理forms。 如果使用GCC,请尝试gcc -C -E somesource.c并查看(预处理)输出。

在20世纪80年代,预处理器是一个单独的程序。

阅读有关cpp预处理器, 预处理器和C预处理器 wikipages的信息。

您甚至可以定义不明确的名称

 #define BAD @*?$ some crap $? 

甚至更可怕的是你可以定义语法上不完整的东西

 #define BADTASTE 2 + 

以后代码BADTASTE 3

实际上,您希望在定义宏时使用括号。 如果你有

 #define BADPROD(x,y) x*y 

然后BADPROD(2+3,4+5)扩展到2+3*4+5 ,编译器理解为2+3*4+5 2+ (3*4) +5 ; 你真的想要

 #define BETTERPROD(x,y) ((x)*(y)) 

因此, BETTERPROD(2+3,4+5)扩展为((2+3)*(4+5))

避免宏参数中的副作用,例如BETTERPROD(j++,j--)

通常,小心使用宏并让它们保持简单。

#define STRING VALUE

只是预处理器用VALUE替换STRING的指令,然后编译器将控制并检查类型

它没有,这是预处理器。 常量的类型取决于使用它的上下文。 例如:

 #define INT_EXAMPLE 257 char foo = INT_EXAMPLE; 

将尝试在char上下文中分配257,该上下文应生成警告,除非char在您的计算机上有超过8位。

#Defines只是文字替代值。 你可能想用

 static const 

因为它尊重范围并且是类型安全的。 试试这个:

 #define main no_main int main() // gets replaced as no_main by preprocessor { return 0; } 

应该给你链接错误。 或者你可以试着欺骗你的老师

 #define I_Have_No_Main_Function main //--> Put this in header file 1.h #include"1.h" int I_Have_No_Main_Function() { return 0; } 

它没有。 #define语句在编译器开始工作之前处理。 基本上,预处理器会搜索并替换您编写的内容并替换它,例如, INTEGER_EXAMPLE所有实例都替换为字符串2

编译器可以根据它的使用位置来决定该类型的类型:

 int x = INTEGER_EXAMPLE; // 2 is an integer char y = INTEGER_EXAMPLE; // 2 is a char 

预处理器无法知道宏定义的类型。 预处理器只会将所有出现的’CHAR_EXAMPLE’替换为’2’。 我会用cast:

 #define CHAR_EXAMPLE ((char)2)