在C语言编程中,有时候需要知道某结构体中某成员的大小,比如使用堆内存来存储结构体中的某成员时,需要知道该成员的大小,才好确定所需申请的空间大小。求某结构体中某成员的大小,你会怎么做?
例子:
typedef struct { char a; char c; short b; int d; char e; }test_struct;
求 d 成员所占内存空间的大小。
方法一
萌新尝试法。。。
我们可以先定义一个结构体变量,然后再使用sizeof求出。
#include <stdio.h> typedef struct { char a; char c; short b; int d; char e; }test_struct; int main(void) { test_struct test_s; printf("sizeof(test_s.d) = %d\n", sizeof(test_s.d)); return 0; }
运行结果:

但是我们为了得到一个成员的大小,而专门定义一个结构体变量,而这个变量也没有其它的用途,有点浪费资源,或者说这种方法low了。
方法二
肉眼观察法。。。
比如在32bit环境下,我们一眼看出d是int类型,就是4个字节,使用sizeof(int)求出。然后想咋用就咋用。这个简单就不讨论了。
方法三
装X法。。。
代码:
#include <stdio.h> typedef struct { char a; char c; short b; int d; char e; }test_struct; int main(void) { printf("sizeof(((test_struct*)0)->d) = %d\n", sizeof(((test_struct*)0)->d)); printf("sizeof(((test_struct*)0)->a) = %d\n", sizeof(((test_struct*)0)->a)); printf("sizeof(((test_struct*)0)->b) = %d\n", sizeof(((test_struct*)0)->b)); printf("sizeof(((test_struct*)0)->c) = %d\n", sizeof(((test_struct*)0)->c)); return 0; }
运行结果:

类似 ((test_struct*)0)->d 这样的用法是个固定用法,把0地址转换为test_struct结构的指针,对于结构体指针,使用 -> 符号就是取其成员,再使用sizeof就可以求得其大小。这里不一定是0地址,其它地址也可以,但一般都会使用0地址。这种方法较方法一的好处就是不用定义一个多余的变量。
这种方法很重要,需要掌握,可能你平时编程不会使用这种方法,但这种方法很重要。在很多优秀的代码中会出现类似形式的宏代码,例如:
上例可封装一个宏定义:
#define MEM_SIZE(type, member) sizeof(((type*)0)->member)
求某成员在结构体中的偏移量:
#define OFFSETOF(type, member) ( (size_t)(&( ( (type*)0)->member ) ) )
求结构体偏移量在C语言头文件中 stddef.h 也有提供,使用方法如:
#include <stdio.h> #include <stddef.h> #define OFFSETOF(type, member) ( (size_t)( &( ( (type*)0 )->member ) ) ) typedef struct { char a; char c; short b; int d; char e; }test_struct; int main(void) { /* stddef.h宏 */ printf("offset(a): %d\n", offsetof(test_struct, a)); printf("offset(c): %d\n", offsetof(test_struct, c)); printf("offset(b): %d\n", offsetof(test_struct, b)); printf("offset(d): %d\n", offsetof(test_struct, d)); printf("offset(e): %d\n", offsetof(test_struct, e)); /* 自定义宏 */ printf("OFFSETOF(a): %d\n", OFFSETOF(test_struct, a)); printf("OFFSETOF(c): %d\n", OFFSETOF(test_struct, c)); printf("OFFSETOF(b): %d\n", OFFSETOF(test_struct, b)); printf("OFFSETOF(d): %d\n", OFFSETOF(test_struct, d)); printf("OFFSETOF(e): %d\n", OFFSETOF(test_struct, e)); return 0; }
运行结果:

使用这个求结构体偏移量的宏我们就可以很好地知道结构体成员的在内存中的存储情况。
以上就是本次分享的求结构体成员的三种方法。重点掌握方法三,因为在很多优秀的代码中都有使用到类似的方法。
如有错误,欢迎指出!谢谢~
看到这里是不是又学到了很多新知识呢~
如果你很想学编程,小编推荐我的C语言/C++编程学习基地【点击进入】!
都是学编程小伙伴们,带你入个门还是简简单单啦,一起学习,一起加油~
还有许多学习资料和视频,相信你会喜欢的!
涉及:游戏开发、常用软件开发、编程基础知识、课程设计、黑客等等......

