在C语言中指针时最精髓的东西,但是指针又是一个比较危险的东西 现在我们不讲指针我们制淡轮 指针的初始化。
指针的初始化离不开NULL 这个符号。
在c中NULL和0的值都是一样的,但是为了目的和用途及容易识别的原因,NULL用于指针和对象,0用于数值的初始化。
对于字符串的结尾,使用'\0',它的值也是0,但是让人一看就知道这是字符串的结尾,不是指针,也不是普通的数值
NULL -->> 指针初始化
0 -->> 数值初始化
‘\0' -->> 字符串结尾符
offset宏的作用
用宏来计算结构体中某一个元素和结构体首元素地址的偏移量。(实质上是通过编译器来计算的)
2.0ffset宏的原理
我们虚拟一个type类型的结构体变量,然后用type.member的方式来访问,这个member元素,继而得到整个menber相对于首地址的偏移量。
宏的定义方法:#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
理解方法:
1.(TYPE *)0 强制类型转换,把0地址强制转换成一个指针,这个指针指向TYPE类型的结构体变量。
2.((TYPE *)0)->MEMBER) (TYPE *)0是一个TYPE类型结构体变量的指针,通过这个指针来访问结果体变量里面的元素member。
3. &((TYPE *)0)->MEMBER)
这个等效于 &(((TYPE *)0)->MEMBER)),得到menber的地址。
container宏
作用:直到结构体变量中某一个变量,用来反推这个结构体变量的指针,有了container宏,我们可以由结构体中的某个变量的指针得到整个结构体的地址。从而到其他元素的指针。
定义如下:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
container_of宏分为两部分,
第一部分:const typeof( ((type *)0)->member ) *__mptr = (ptr);
通过typeof定义一个member指针类型的指针变量__mptr,(即__mptr是指向member类型的指针),并将__mptr赋值为ptr。
第二部分: (type *)( (char *)__mptr - offsetof(type,member) ),通过offsetof宏计算出member在type中的偏移,然后用member的实际地址__mptr减去偏 移,得到type的起始地址,即指向type类型的指针。
第一部分的目的是为了将统一转换为member类型指针。