1.各数据类型所占字节大小
对于不同的处理器,所占空间大小取决于编译器的类型
16位编译器
char : 1Byte
char* : 2Byte //也即指针变量
short int : 2Byte
int : 2Byte
float : 4Byte
double : 8Byte
long : 4Byte
long long : 8Byte
32位编译器
char : 1Byte
char* : 4Byte
int : 4Byte
short int : 2Byte
float : 4Byte
double : 8Byte
long : 4Byte
long long : 8Byte
64位编译器
char : 1Byte
char* : 8Byte
int : 4Byte
short int : 2Byte
float : 4Byte
double : 8Byte
long : 8Byte
long long : 8Byte
2.机器大小端问题
关于大小端:
大端存储:高字节存低地址,即高位先存;(合乎阅读习惯)
小端存储:低字节存低地址,即低位先存。
例如:变量0x11223344,大小端存储如下1
2
3
4
5地址 大端 小端
0x6ff710 11 44
0x6ff711 22 33
0x6ff712 33 22
0x6ff713 44 11
判断机器大小端方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26方法一:
// 利用指针
void test(){
int a=0x11223344;
char *p=(char*)&a; //取变量a的低地址
if(0x11==*p)
printf("大端\n");
else
printf("小端\n");
}
方法二:
// 利用联合体
void test(){
union t{
int i;
char c;
}t1;
t1.i=1;
if(1==t1.c)
printf("小端\n");
else
printf("大端\n");
}
3.结构体
描述下面宏XXX的作用
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define XXX(ptr, type, member) ({ \
const typeof( ((type )0)->member ) mptr = (ptr); \
(type )( (char )mptr - offsetof(type,member) );})
假设存在结构体:1
2
3
4
5struct s{
type1 A;
type2 B;
type3 C;
}s1;
变量类型用typex代替是避免考虑内存中字节对齐的问题,现在s1在内存中的分布应该是这样的(假设的数据长度):1
2
3
4地址 变量
0x80000 A
0x80004 B
0x8000a C
上面的宏运算涉及到的三个参数分别为:
ptr: 指向结构体成员的指针,比如type2 p=&B
type: 结构体类型,比如struct s
member: 结构体成员名字,比如B
那么先看宏offsetof,((TYPE )0)先将零类型转换为TYPE类型指针,((TYPE )0)->MEMBER将访问TYPE结构体中的数据成员MEMBER,然后&((TYPE )0)->MEMBER取数据成员的地址,其实时取到了MEMBER成员相对于其所在结构体的偏移,最后(size_t)&((TYPE )0)->MEMBER实现结果类型转换
再看宏XXX,const typeof(((type )0)->member) mptr=(ptr);将结构体成员指针赋值指针变量mprt,(type)((char*)__mptr-offsetof(type,member));是用结构体数据成员的指针减去该成员在结构体中的偏移量,得到结构体的基指针,最后强制转换成结构体指针类型
综上所述,该宏定义实现了根据结构体某成员变量获取该结构体基地址。