学好C和OC,漂亮的宏定义很重要,使用好宏定义,不仅能减少代码出错机率,提高可读性,同时方便移植,代码看起来也简洁美观,何乐而不为呢。
我们经常在程序中反复使用的地方使用宏定义。
当然我们也可以重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植,当然定义类型使用最多的还是typedef。
#define uint16 unsigned int
typedef unsigned long int uint32;
常用的宏定义有两种:带参数的宏定义
和不带参数的宏定义
。
不带参数的宏定义
- 使用格式:#define 宏名 字符串
- 作用:将程序中所有出现宏名的地方都用字符串进行替换
- 例子:#define SIZE 100
带参数的宏定义
- 使用格式:#define 宏名(行参列表) 字符串
- 作用:用实参替换行参,其他字符串原样保留
- 例子:#define S(a, b) ((a)*(b))
- 注意:字符串中参数最好加上括号,防止出现由优先级导致的bug。
- 例子:S(3+2, 5+7); —> 3+2*5+7 —> 20
宏定义#和##用法
“#”是”字符串化”的意思。出现在宏定义中的”#”是把跟在后面的参数转换成一个字符串。
1
2#define STRCPY(dst, src) strcpy(dst, #src)
STRCPY(buff, abc) 相当于 strcpy(buff, "abc")“##”是一种分隔连接方式,它的作用是先分隔,然后进行强制连接。
1
2#define CONNECT(x) T_##x
CONNECT(abc) 相当于 T_abc值得注意的是如果##后的参数本身也是一个宏的话,##会阻止这个宏的展开,也就是只替换一次。
1
2
3
4
5
6
7
8
9
10
int main()
{
STRCPY(STRCPY(var1,var2),var2);
// 这里是否会展开为: strcpy(strcpy(var1_p,"var2")_p,"var2“)?
// 答案是否定的:
// 展开结果将是: strcpy(STRCPY(var1,var2)_p,"var2")
// ## 阻止了参数的宏展开!
// 如果宏定义里没有用到 # 和 ##, 宏将会完全展开
}
多行宏定义
在需要换行的地方使用”/“
1 |
|
常用预处理命令
防止一个头文件重复包含
1
2
3
4
//头文件内容条件编译(版本测试)
1
2
3
4
5
6
7
//...
//debugging code here
//...