目录
一,翻译环境
编译器
链接器
二,执行环境
三,预处理详解
预定义符号
#define
#
##
带副作用的宏参数
宏和函数的对比
#undef
命令行定义
条件编译
文件包含
其他预处理指令
在ANSI C的任何一种实现中,存在两个不同的环境
- 翻译环境,将源代码转换为可执行的机器指令;
- 执行环境,用于实际执行代码;
一,翻译环境
预编译/预处理(文本操作)
编译
《编译原理》
汇编
《程序员的自我修养》
二,执行环境
程序执行过程
三,预处理详解
预定义符号
__FILE__ //进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如文件编译器遵循ANSI C,其值为1,否则未定义(gcc支持、vs不支持)
int main()
{
printf("%s\n", __FILE__); //F:\VS\Project1\test.c
printf("%d\n", __LINE__); //1990
printf("%s\n", __DATE__); //Aug 1 2021
printf("%s\n", __TIME__); //10:23 : 43
}
#define
#define定义的标识符
#define MAX 1000 //可替换数值
#define reg register //可替换关键字
#define do forever for(;;) //可替换一段语句
#define CASE break;case //可替换一段代码
//可替换多行代码(\续行符)
#define DEBUG_PRINT printf("file:%s\tline:%d\tdate:%s\ttime:%s\n",\
__FILE__, __LINE__, \
__DATE__, __TIME__)
#define定义宏
#define name( parament-list ) stuff
#define SQUARE(x) x*x
int main()
{
int ret = SQUARE(4); //先传参,在替换
printf("%d", ret);
}
//结果:16
注:
#define SQUARE(x) x*x
int main()
{
int ret1 = SQUARE(3 + 1); //3+1*3+1
int ret2 = 3 * SQUARE(3 + 1); //3*3+1*3+1
printf("%d %d", ret1, ret2);
}
//结果:7 13
#define SQUARE(x) ((x)*(x))
int main()
{
int ret1 = SQUARE(3 + 1); //(3+1)*(3+1)
int ret2 = 3 * SQUARE(3 + 1); //3*((3+1)*(3+1))
printf("%d %d", ret1, ret2);
}
//结果:16 48
#define替换规则
#define M 100
#define MAX(x,y) ((x)>(y)?(x):(y))
int main()
{
int ret = MAX(10, M);
return 0;
}
注:
#define M 100
int main()
{
printf("M"); //此M不会被替换
return 0;
}
#
#define fun(x) #x //即转换为“x”
int main()
{
char str[] = fun(abcd);
printf("%s", str);
return 0;
}
//结果:abcd
#define print(x, Format) printf("The value of "#x" "Format"!\n", x)
int main()
{
int num1 = 10;
float num2 = 20;
print(num1, "%d"); //printf("The value of ""num1"" %d!\n", num1)
print(num2, "%f"); //printf("The value of ""num2"" %f!\n", num2)
return 0;
}
//The value of num1 10!
//The value of num2 20.000000!
##
#define CAT(x, y) x##y
int main()
{
char str[] = CAT("ab", "cd");
int num1 = 10;
int num2 = CAT(num, 1);
return 0;
}
带副作用的宏参数
#define MAX(x, y) ((x)>(y)?(x):(y))
int main()
{
int a = 5;
int b = 8;
int ret = MAX(a++, b++); //((a++)>(b++)?(a++):(b++))
printf("%d %d %d", ret, a, b); //9 6 10
}
宏和函数的对比
宏,通常被用于执行简单的运算;
宏优势
宏劣势
//宏,可传类型参数
#define MALLOC(num,type) (type*)malloc(num*sizeof(type))
int main()
{
//(int*)malloc(10*sizeof(int))
MALLOC(10, int);
return 0;
}
注:
#undef
#define M 100
int main()
{
#undef M
printf("%d", M); //M为未定义的标识符
return 0;
}
命令行定义
条件编译
#define M 100
int main()
{
#ifndef N
printf("%d", M); //如未定义了N,即编译此语句
#endif
#ifdef M
printf("%d", M); //如定义了M,即编译此语句
#endif
return 0;
}
文件包含
#include
头文件包含方式
注:
嵌套文件包含
其他预处理指令
《高质量C/C++编程指南》
《C语言深度剖析》