目录
预定义符号
__FILE__ //进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
#define
语法
#define name stuff
替换规则:
在程序中扩展#define定义符号和宏时,需要涉及几个步骤。
1. 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。
2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值替换。
3. 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。
注意:
1. 宏参数和#define 定义中可以出现其他#define定义的变量。但是对于宏,不能出现递归。
2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
#和##
在#define中,#号表示字符串化操作,将宏参数转化为字符串;而##号表示拼接操作,将多个宏参数拼接成一个新的标识符或表达式。下面是两个例子:
- #操作符:
#define STR(x) #x
printf("%s\n", STR(hello world)); // 输出hello world
在上面的例子中,#操作符将宏参数x转化为字符串"hello world",然后传递给printf函数,输出它的值。
2.##操作符:
#define CONCAT(x, y) x ## y
int xy = CONCAT(3, 4); // 定义变量xy,值为34
在上面的例子中,##操作符将宏参数x和y拼接成一个新的标识符或表达式。在这里,它将x和y拼接成一个整数34,定义了一个新的变量xy,其值为34。
宏和函数对比
宏和函数是两种不同的代码结构,有不同的用途和特点。下面是它们的对比:
-
宏是由预处理器展开的代码,而函数是由编译器编译的代码。宏在编译前就已经被展开了,而函数在程序运行时被调用。
-
宏可以在程序中进行简单的文本替换,而函数可以执行更复杂的任务。宏通常用于执行简单的重复操作,而函数通常用于执行更复杂的逻辑操作。
-
宏具有更广泛的适用性,可以用于各种目的,例如定义常量、运算符、条件语句等。函数的用途比较特定,通常用于执行某个特定的操作或任务。
-
宏使用起来比较简单,但可读性差。由于宏在编译前展开,因此在代码中看不到其实际执行的代码。函数使用起来比较复杂,但更容易理解和调试。
-
宏的执行速度比函数快,因为它们在编译前就已经展开了。函数的执行速度比较慢,因为它们需要在程序运行时被调用,并且需要在堆栈中分配内存空间。
综上所述,宏和函数各有优缺点,应根据具体情况选择使用。一般来说,如果需要执行简单的操作或逻辑,应该使用宏;如果需要执行复杂的操作或任务,应该使用函数。
文件包含< >和" "
" "查找策略:先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标准位置查找头文件。如果找不到就提示编译错误。
< >查找策略:查找头文件直接去标准路径下去查找,如果找不到就提示编译错误
#pragma once 可以避免头文件被重复引用