zoukankan      html  css  js  c++  java
  • 这种求C语言结构体成员大小的方法,萌新们掌握了吗

    在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 ", sizeof(test_s.d));

        return 0;

    }

    运行结果:


     

    但是我们为了得到一个成员的大小,而专门定义一个结构体变量,而这个变量也没有其它的用途,有点浪费资源,或者说这种方法low了。


     

    方法二

    肉眼观察法。。。。。。

    比如在32bit环境下,我们一眼看出d是int类型,就是4个字节,使用sizeof(int)求出。然后想咋用就咋用。这个简单就不讨论了。

    方法三

    装逼法。。。。。。

    代码:

    #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 ", sizeof(((test_struct*)0)->d));

        printf("sizeof(((test_struct*)0)->a) = %d ", sizeof(((test_struct*)0)->a));

        printf("sizeof(((test_struct*)0)->b) = %d ", sizeof(((test_struct*)0)->b));

        printf("sizeof(((test_struct*)0)->c) = %d ", 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 ", offsetof(test_struct, a));

        printf("offset(c): %d ", offsetof(test_struct, c));

        printf("offset(b): %d ", offsetof(test_struct, b));

        printf("offset(d): %d ", offsetof(test_struct, d));

        printf("offset(e): %d ", offsetof(test_struct, e));

        /* 自定义宏 */

        printf("OFFSETOF(a): %d ", OFFSETOF(test_struct, a));

        printf("OFFSETOF(c): %d ", OFFSETOF(test_struct, c));

        printf("OFFSETOF(b): %d ", OFFSETOF(test_struct, b));

        printf("OFFSETOF(d): %d ", OFFSETOF(test_struct, d));

        printf("OFFSETOF(e): %d ", OFFSETOF(test_struct, e));

        return 0;   

    }

    运行结果:


     

    使用这个求结构体偏移量的宏我们就可以很好地知道结构体成员的在内存中的存储情况。


     

    以上就是本次分享的求结构体成员的三种方法。重点掌握方法三,因为在很多优秀的代码中都有使用到类似的方法。

    如有错误,欢迎指出!另外如果你想更好的提升你的编程能力,好好学习C/C++编程知识的话!那么你很幸运~“点击链接”加入C/C++企鹅圈,这里还有一些你可能不知道的趣事分享哟。

  • 相关阅读:
    Java实时读取日志文件
    Trie树的应用:查询IP地址的ISP
    vue.extend,mixins和vue.component的区别
    前端性能优化10个方面
    vue组件和插件是实现
    vue指令用法
    promise retry实现
    linux管道与重定向
    linux文件颜色与类型
    linux文件权限说明
  • 原文地址:https://www.cnblogs.com/mu-ge/p/13809578.html
Copyright © 2011-2022 走看看