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

  • 相关阅读:
    HDU 5528 Count a * b 欧拉函数
    HDU 5534 Partial Tree 完全背包
    HDU 5536 Chip Factory Trie
    HDU 5510 Bazinga KMP
    HDU 4821 String 字符串哈希
    HDU 4814 Golden Radio Base 模拟
    LA 6538 Dinner Coming Soon DP
    HDU 4781 Assignment For Princess 构造
    LA 7056 Colorful Toy Polya定理
    LA 6540 Fibonacci Tree
  • 原文地址:https://www.cnblogs.com/Cqlismy/p/11428859.html
Copyright © 2011-2022 走看看