目录
翻译环境和执行环境
预定义符号
#define定义标识符
续行符\
#define定义宏
再说一下,#define其实就是替换
#和##
宏和函数的对比
命名约定
#undef
命令行定义
条件编译
文件包含
避免头文件重复引用,否则会增加代码长度
翻译环境和执行环境
在C中存在两个不同的环境,分别是翻译环境和执行环境,翻译环境又包括编译和链接两种,然后生成目标文件和可执行文件。编译本身也分为几个阶段:预处理选项、编译选项、汇编。
预定义符号
__FILE__ 这是文件路径
__LINE__ 这是所在行号
__DATE__
__TIME__
__STDC__
Printf(“%s”,__FILE);
#define定义标识符
#define MAX 100
续行符\
Printf(“%s\t%d\
\t%f\n”,”张三\
”,34,3.5)
#define定义宏
#define SQUARE(X) X*X
Printf(“%d”,SQUARE(5));
再说一下,#define其实就是替换
#和##
#ch等于”ch”,字符串
ch等于c##h,合并两个
#define PRINT(X,Y) printf("this value of " #Y " is " X"\n",Y)//Y当成了字符串,X当成了"%d",然后把Y的值给了Xint main()
{PRINT("%d", 3 + 4);PRINT("%d", 4 + 8);return 0;
}
宏和函数的对比
属性 | #define定义宏 | 函数 |
代码长度 | 每次使用时,宏代码都会被插入到程序中,除了非常小的宏之外,程序的长度会大幅度增长 | 函数代码只出现于一个地方,每次使用这个函数时,都调用那个地方的同一份代码 |
执行速度 | 更快 | 存在函数的调用和返回的额外开销,所以相对慢一些 |
操作符优先级 | 宏参数的求值是在所有周围表达式的上下文环境里,除非加上括号,否则邻近操作符的优先级可能会产生不可预料的后果,所以建议宏在书写的时候多些括号 | 函数参数只在函数调用的时候求值一次,它的结果值传递给函数,表达式的求值结果更容易预测 |
带有副作用的参数 | 参数可能被替换到宏体中的多个位置,所以带有副作用的参数求值可能会产生不可预料的结果 | 函数参数只在传参的时候求值一次,结果更容易控制 |
参数类型 | 宏的参数与类型无关,只要对参数的操作是合法的,它就可以使用于任何参数类型 | 函数的参数是与类型有关的,如果参数的类型不同,就需要不同的函数 |
调试 | 宏是不方便调试 | 函数是可以逐语句调试 |
递归 | 宏不能递归 | 函数可以递归 |
命名约定
宏名全大写,函数名不全大写
#undef
用于移除一个宏定义
#undef NAME
命令行定义
Int a[MAX]
Int i = 0;
For(i=0;i<MAX;i++)
{
A[i] = i+1;
}
For(i=0;i<MAX;i++)
{
Printf(“%d\n”,a[i]);
}
在命令行里为MAX给值
条件编译
#define __DEBUG__ 定义
#ifdef __DEBUG__ 如果定义
#ifnde __DEBUG__ 如果不定义
#endif 用来结束
只是判断它是不是被定义,如果不满足条件,在预处理阶段会消失。
文件包含
#include ”Pet.h” 本地文件包含,如果找不到就去库文件找
#include <Pet.h> 直接去库文件找
避免头文件重复引用,否则会增加代码长度
在每一个头文件前面加上#pragma once,其他源文件如果引用这个头文件两三个,都只会得到一个。