zoukankan      html  css  js  c++  java
  • 宏offsetof分析

    1、前言

    在C语言的结构体中,由于字节对齐的问题,所以成员的地址并不能直接根据数据类型的大小进行计算,使用宏offsetof可以获得结构体成员相对于结构体首地址的字节偏移量。

    2、offsetof宏实现

    在C标准库中offsetof的声明如下,需要包含头文件<stddef.h>:

    size_t offsetof(type, member);

    参数:

             type:结构体类型

             member:结构体中成员的名称

    返回值:

             返回类型为size_t的值,表示type中member的偏移量

    该宏在Linux内核源码内的实现如下:

    #define offsetof(TYPE, MEMBER)   ((size_t)&((TYPE *)0)->MEMBER)

    通过上面这个宏为什么能获取到结构体某个成员的偏移地址呢?首先,偏移地址的计算方法为:

    当前的成员地址-结构体首地址=偏移地址

    在offsetof宏中,将0地址强制转换成了(TYPE *)类型,也就是说结构体的首地址为0,所以根据偏移地址计算方法,可以知道当前成员的地址也就等于偏移地址,所以宏offsetof将成员的地址取出并返回,获得的就是某个成员的偏移地址了,返回值为size_t类型,需要引起一定的注意。

    3、实例

    下面是一个offsetof的使用实例,代码如下所示:

    #include <stdio.h>
    #include <stddef.h>
    #include <stdlib.h>
    
    struct s {
        int i;
        char c;
        double d;
        char a[];
    };
    
    int main(int argc, char *argv[])
    {
        printf("sizeof(struct s)=%zd
    ", sizeof(struct s));
        printf("offsets: i=%zd; c=%zd; d=%zd; a=%zd.
    ",
                offsetof(struct s, i), offsetof(struct s, c),
                offsetof(struct s, d), offsetof(struct s, a));
        
        exit(EXIT_SUCCESS);
    }

    使用gcc编译后运行结果如下所示:

    由于字节对齐的原因,所以结构体s的大小为16个字节,假设结构体首地址从0开始,由于int类型占用4字节,所以地址0到3为变量i所用,char类型占用1字节,地址4为变量c所用,由于需要字节对齐并且double类型的开始地址必须是8的整数倍,因此地址5到7被填充,double类型占用8字节,地址8到15被变量d所用,a的地址则从地址16开始,因此,通过宏offsetof便可以得到结构体成员的偏移地址。

    参考:

    https://www.runoob.com/cprogramming/c-macro-offsetof.html

    https://www.cnblogs.com/litifeng/p/7685378.html

  • 相关阅读:
    HBuilder手机Iphone运行提示“未受信用的企业级开发者”
    在阿里云服务器ubuntu14.04运行netcore
    微信图片上传
    一段sql的优化
    设计模式之单例模式(Singleton)
    PDF.NET+EasyUI实现只更新修改的字段
    操作系统进程调度之分时,优先,分时优先
    2020最新Servlet+form表单实现文件上传(图片)
    Php7+Mysql8实现简单的网页聊天室功能
    JavaSwing+Mysql实现简单的登录界面+用户是否存在验证
  • 原文地址:https://www.cnblogs.com/Cqlismy/p/11428859.html
Copyright © 2011-2022 走看看