c程序不直接编译成二进制,而是先编译成汇编代码,借助汇编代码的编译器编译成二进制,借前人的轮子。
define定义字符串
需要加上双引号,可以使用续接符
宏定义注释符
程序翻译过程:
1.预处理:头文件展开,去注释,宏替换,条件编译
2.编译 :将c语言转换成汇编语言
3.汇编 :将汇编语言转换成可重定向目标文件
4.链接:自身程序+库文件进行关联,形成可执行文件
在预处理时,去注释操作先于宏替换
注释的本质是替换文本为空格,程序先执行注释的操作,BSC就只是定义了,并没有值,所以在宏替换的时候,printf之前的BSC就被空内容替换。
c自身的注释符也是同样,程序去注释将后一条宏定义替换成空格,所以BMC为空,EMC没有定义。
不能写这样的注释。
宏定义的表达式
宏不会替换常量字符串中的内容。
用宏定义的内容中有多条表达式时,推荐用do-while-zero结构写。防止出错(if语句不加大括号)。
无论有没大括号,宏都能正确的替换。
总结:在使用多语句定义宏时,推荐用do-while-zero结构
#undef
1.宏在任意位置都是能定义的,不是只能定义在main函数上面。
2.宏的有效范围:从定义开始往下。
#undef是取消宏的定义,用来限定宏的使用范围。
函数的调用是在代码的执行期间,但编译时已经完成宏替换
#ifdef && #ifndef
#ifdef只有#else两个分支,是用来判断宏是否被定义,而不是判断宏的值是否为真。
结束时用#endif匹配#ifdef,由于#ifdef只有两个分支,(与#else)通常多使用#if
#if
#if,#elif,#else,能写多个分支语句,同样需要#endif匹配,否则程序会报错。
#if能模拟#ifdef,#if defined( ),#if !defined(),要加上d,在括号中写要进行判断的宏。
#if时用来判断宏的值是否为真,也能判断一些字面常量值的真假。还能判断表达式的真假。
如果宏没有定义,则该表达式为假
要逻辑判断的条件有多个时
总结:条件编译本质是编译器根据特定情况对代码进行裁剪。
好处是保留当前最需要的代码,减小代码量;写出跨平台的代码,使代码在不同平台也能用相同的表现。
#error&&#line&&#pragma
#error使系统报错,让程序停止运行
#pragma message(""),双引号必须写,与#error作用类型,不过不会使程序停止,能运行。
#line修改文件与行号
#&&##
相邻字符串会自动连接。
#在宏中能将符号转换成字符串,带引号的那种
##能在宏中连接两个符号