码迷,mamicode.com
首页 > 其他好文 > 详细

如何求结构体成员的偏移地址

时间:2015-08-12 16:49:25      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:c语言   sizeof   

C 语言中允许将值为 0 的变量强制转换成任一类型的指针,转换结果是一个NULL指针;

(type*)0 // 一个 type 类型的NULL指针

用这个指针访问结构体内的成员是非法的,但是

&(((type*)0)->field)

是为了计算 field 的地址 ,编译器不会产生访问 field 的代码,只会根据 type 的布局和起始地址在编译期计算这个地址(常量)。而又因为初始地址为 0,故该地址的值就是该结构体成员相对于结构体基址的偏移。

(size_t)&(((type*)0)->field)

结构体的 sizeof 的相关知识:
对 32 位操作系统,默认按 4 字节对齐;
sizeof(union),结果是 union 占用内存最大成员的大小(各成员共享内存)

#include <iostream>
using namespace std;
#define ISUNSIGNED(x) ((x > 0) && (~x > 0))
#define OffSet(type, field) ((size_t)&(((type*)0)->field))
int main()
{
    struct A{
        char a;
        int b;
        float c;
        double d;
        char e;
        union {
            char f[100];
            struct {
                int g[50];
            } h;
        }i;
        bool j;
    } s;
    cout << sizeof(A) << endl; // 232
    cout << "a 的起始偏移:"<< OffSet(A, a) << endl; // 0
    cout << "b 的起始偏移:"<< OffSet(A, b) << endl; // 4
    cout << "c 的起始偏移:"<< OffSet(A, c) << endl; // 8
    cout << "d 的起始偏移:"<< OffSet(A, d) << endl; // 16
    cout << "e 的起始偏移:"<< OffSet(A, e) << endl; // 24
    cout << "i 的起始偏移:"<< OffSet(A, i) << endl; // 28
    cout << "j 的起始偏移:"<< OffSet(A, j) << endl; // 228


    int p = 1;
    unsigned int q = 1;
    cout << p << " " << ~p << endl; // 1 -2
    cout << q << " " << ~q << endl; // 1 4294967294
    cout << "p是否是无符号数:" << ISUNSIGNED(p) << endl; // 0
    cout << "q是否是无符号数:" << ISUNSIGNED(q) << endl; // 1
    return 0;
}

参考:《程序员笔试面试宝典》

版权声明:本文为博主原创文章,未经博主允许不得转载。

如何求结构体成员的偏移地址

标签:c语言   sizeof   

原文地址:http://blog.csdn.net/quzhongxin/article/details/47446685

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!