标签:笔试 code java this 符号 nes parent key nio
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 占用内存最大成员的大小(各成员共享内存)
编译器是依照什么样的原则进行对齐的?
1.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,对于short型为2,对于int, float类型,其自身对齐值为4,对于double类型其自身对齐值为8,单位字节。
2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
3.指定对齐值:#pragma pack (value)时的指定对齐值value。
4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。
#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 B{
char f[100];
struct C{
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;
}
以上结构体分析:
struct A{
char a;
int b;
float c;
double d;
char e;
union B{
char f[100];
struct C{
int g[50];
} h;
}i;
bool j;
} s;
一个成员在内存中补位所占的内存,决定于该成员之后的成员类型。
參考:《程序猿笔试面试宝典》
怎样求结构体成员的偏移地址 || 结构体的 sizeof 总结
标签:笔试 code java this 符号 nes parent key nio
原文地址:http://www.cnblogs.com/mthoutai/p/7205104.html