#define定义的宏

目录

1.什么是#define

2.宏的功能:替换宏与值

① 方便检测

② 方便维护

③ 简化写法

3. 编译器替换规则

4. 宏的一些使用细节    和    # 

5. 两道宏的进阶题目


1.什么是#define

举个例子:这里的PI就是宏的名字,3.1416就是宏的值

#define PI 3.1416//这里的PI就是宏的名字,3.1416就是宏的值

2.宏的功能:替换宏与值

① 方便检测

比如你在程序中,需要多次用到1这个值,但是值的含义又不相同,为了增加可读性,让检查代码的时候能够看到1就知道代表什么,这个时候你就可以给不同含义的1定义不同的宏的名字。

② 方便维护

如:可以用来定义数组容量 #define MAX_SIZE 100

后续使用的时候可以这样使用: int a[MAX_SIZE];

以后如果容量少了,直接修改这个宏,则使用的地方都跟着得到最新的了,就不需要一个个更改

③ 简化写法

如:可以这样的定义: #define unsigned int UINT

则后续的时候就可以这样的写了: UINT a;//与unsigned int a;等价

3. 编译器替换规则

在预处理的过程中,将所有的含有宏定义的名字替换成值

#define a 2+3

int b = 2 * a ;                         //这个时候就替换成了 int b = 2 * 2 + 3 ; 所以要注意多添加括号

printf ( " %s " , a is 2+3 ) ;    //而这里要注意字符串常量并不会被替换,打印结果是 a is 2+3

4. 宏的一些使用细节    和    # 

① 首先你要知道,字符串有自动连接的特点

char *p = " welcome_" " to_you\0 ";    //_表示空格

printf(" %s " , welcome_to_you) ;        //打印welcome to you

printf(" %s " , p ) ;                              //打印welcome to you

② #的使用 

可以把宏参数编程对应的字符串,当你想让字符串里出现宏的时候就可使用。比如

***********仔细看代码**********

int i = 10 ;

#define PRINT (FORMAT , VALUE)  printf("the value of "#VALUE " is " FORMAT " \n " , VALUE) ;

PRINTF("%d" ,i+3);                                          //打印 the value of i+3 is 13          

5. 两道宏的进阶题目

① 写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。

② offsetof宏的实现

#define offsetof(StructType, MemberName) (size_t)&(((StructType *)0)->MemberName)

StructType是结构体类型名,MemberName是成员名。具体操作方法是:

1、先将0转换为一个结构体类型的指针,相当于某个结构体的首地址是0。此时,每一个成员的偏移量就成了相对0的偏移量,这样就不需要减去首地址了。

2、对该指针用->访问其成员,并取出地址,由于结构体起始地址为0,此时成员偏移量直接相当于对0的偏移量,所以得到的值直接就是对首地址的偏移量。

3、取出该成员的地址,强转成size_t并打印,就求出了这个偏移量。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shn!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值