C语言,结构体成员的地址
先回顾一个基础的知识,不同类型的数据在16位,32位,64位的机器分别占用多少字节。
可以看到long类型的数据比较特殊,在写跨平台的应用时需要注意,最好是避免使用
定义两个结构体
typedef struct _demo_node_{ struct _demo_node_* pprenode; struct _demo_node_* pnextnode; unsigned long member_num; unsigned short age; char addr[0]; }demo_node; typedef struct { char province[8]; char city[8]; }address_info;
写程序来验证一下,结构体本身的地址,以及它包含的成员的地址,有什么样的联系
#include <stdio.h> #include <malloc.h> #include <string.h> typedef struct _demo_node_{ struct _demo_node_* pprenode; struct _demo_node_* pnextnode; unsigned long member_num; unsigned short age; char addr[0]; }demo_node; typedef struct { char province[8]; char city[8]; }address_info; int main(void) { demo_node* person = NULL; person = (demo_node*)malloc(sizeof(demo_node)+sizeof(address_info)); if(NULL == person) { printf("malloc demo_node failed "); return -1; } printf("person结构体的地址 = 0x%0x ",person); printf("person->pprenode的地址 = 0x%0x ",&(person->pprenode)); printf("person->pnextnode的地址 = 0x%0x ", &(person->pnextnode)); printf("person->member_num的地址 = 0x%0x ", &(person->member_num)); printf("person->age的地址 = 0x%0x ", &(person->age)); printf("person->addr的地址 = 0x%0x ", &(person->addr)); free(person); return 0; }
采用windows的64位编译器编译,程序输出的结果为
person结构体的地址 = 0x1f1420 person->pprenode的地址 = 0x1f1420 person->pnextnode的地址 = 0x1f1428 person->member_num的地址 = 0x1f1430 person->age的地址 = 0x1f1434 person->addr的地址 = 0x1f1436
我们来分析一下为什么是这样的结果:
- 结构体指针person的地址,与它指向的结构体的第一个成员(person->pprenode)地址是一样的,都是0x1f1420
- pprenode和pnextnode都是指针变量,由于指针变量在64位机器中占8个字节,所以 person->pnextnode的地址 = 8 + person->pprenode的地址 = 0x1f1428 person->member_num的地址 = 8 + person->pnextnode的地址 = 0x1f1430
- member_num是unsigned long类型的变量,在windows的64位机器中占4个字节,所以person->age的地址 = 4 + person->member_num的地址 = 0x1f1434
- age是unsigned short类型的变量,可以等同于short占用的字节,都是2,所以person->addr的地址 = 2 + person->age的地址 = 0x1f1436
关于结构体成员地址,就简单介绍到这里了!
细心的同学一定发现了demo_node 结构体中char addr[0] 这个成员,这其实是个占位符,至于它的用法,可以看我的另一篇文章《C语言,变长数组的用法》,还是在这个示例代码的基础上进行介绍,方便快速理解。