zoukankan      html  css  js  c++  java
  • offsetof宏的实现

    1、c语言的结构体中,因为字节对齐的问题,导致成员地址并不能根据类型的大小进行计算。例如:

    struct test {
        char ch;
        int a;
    }
    printf("test的大小=%d",sizeof(struct test));   //答案是8
    /*注意下面第二个char *,必须是char型指针(和结构体第一个成员类型一致),
    **因为你强制转换的是一个地址,所以必须用指针类型。
    **另外一个地址只有有了类型才可以进行加减运算,否在地址+1不知道要移动几个字节。
    */
    int *p=(int *)(char *)&test+1; //错误,因为char并不是占用1个字节,而是4个字节 int *p=(int *)(char *)%test+4; //正确

    2、offsetof宏的实现如下:

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

    哈哈,复杂吧,解释一下:由于造成空洞的对齐动作是由编译器负责完成的,这里有一个欺骗编译器的指令:((TYPE *)0),

    意思是定义一个指向TYPE类型的指针,且该指针值(也就是该type类型的地址)为0,当然这是不可能引用成功的,0地址早已

    被操作系统保护起来了:),那么这么做意义何在?我们知道:当前地址-首地址=偏移量,如果首地址为0呢?当前地址是不是

    就是偏移量了?呵呵,明白了吧,强制把0转换为type类型的指针,并不是为了访问0地址的值,而是为了从编译器里套话(假设首地址

    为0时,当前地址是多少?)。

    最后要注意:因为我们得到的是一个地址,所以要设置为size_t类型,如果设为int类型,编译器就要警告了,因为int和size_t的大小不相同。

    最后以编译器的警告信息作为本文章的结尾吧:

    warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  • 相关阅读:
    andriod 支付宝类似界面图片加文字
    评分条RatingBar Android
    Android 进度条对话框ProgressDialog
    Android 日期对话框DatePickerDialog
    andriod GridLayout
    android:TableLayout表格布局详解
    ArcGIS 10 SP5中文版(ArcGIS10补丁5中文版)
    Engine中如何进行七参数投影转换?
    如何去除栅格影像的黑边?
    资管机构年中规模排名出炉:中信资管规模超万亿
  • 原文地址:https://www.cnblogs.com/litifeng/p/7685378.html
Copyright © 2011-2022 走看看