#include <stdio.h>
struct A {
int i;
char j;
char * ptr;
long Array[100];
char b[2];
char * c;
};
#define PRINT_ME (char *)&(((struct A *)0)->c)
int main() {
printf("%d/n", (int)PRINT_ME);
}
struct A {
int i;
char j;
char * ptr;
long Array[100];
char b[2];
char * c;
};
#define PRINT_ME (char *)&(((struct A *)0)->c)
int main() {
printf("%d/n", (int)PRINT_ME);
}
printf("%d/n", PRINT_ME);
这句话是打印PRINT_ME,其中格式是数字形式打印
这句话是打印PRINT_ME,其中格式是数字形式打印
struct A {
int i;
char j;
char * ptr;
long Array[100];
char b[2];
char * c;
};
定义了一个结构体A
其中包含了一些变量和指针
int i;
char j;
char * ptr;
long Array[100];
char b[2];
char * c;
};
定义了一个结构体A
其中包含了一些变量和指针
下面我们来看PRINT_ME是个什么东东
#define PRINT_ME (char *)&(((struct A *)0)->c)
首先它是通过一个宏定义的
下面进行解剖
(char *)是个强制类型转化,就是后面得最终结果按照char *来理解。
(char *)是个强制类型转化,就是后面得最终结果按照char *来理解。
&这个是取得后面得地址
(((struct A *)0)->c)
这个是一个整体,怎么理解呢?
下面再分解
这个是一个整体,怎么理解呢?
下面再分解
((struct A *)0)
这个也是一个强制类型转化,把0强制类型转化成struct A*结构
0怎么理解呢,表示结构体A得起始地址为0开始。
然后取得struct A中变量c得相对偏移量。
然后取得struct A中变量c得相对偏移量。
那么最终计算结果是:
struct A {
int i;//4 计算机中整形理解为4个字节
char j;//4个字节,计算机对齐方式为4个字节一对齐
char * ptr;//4个字节
long Array[100];//4*100=400
char b[2];//2*2=4字节
char * c;//其实地址:4+4+4+400+4=416
};
struct A {
int i;//4 计算机中整形理解为4个字节
char j;//4个字节,计算机对齐方式为4个字节一对齐
char * ptr;//4个字节
long Array[100];//4*100=400
char b[2];//2*2=4字节
char * c;//其实地址:4+4+4+400+4=416
};
所以这个程序最终输出为416
char b[2];//2*2=4字节为什么不是4*2?
这个是对齐格式决定得,计算机在存储得时候要有对齐得,32bits得机器,本身就是4个字节一对齐,如果是数组,那么就可以优化为2个字节,
上面那个其实也是占两个字节,但是,由于四个字节对齐,没有其他变量可以补上剩余的2个,所以造成2个字节得浪费。
后面这个是char型,正好互补了空间。
所以是2*2