哇噻~~俩都是10多级的大人物呦~~~
我个11级的就是来打个酱油呦~~~.
楼主, 你可以做一个这两个实验:
实验一:
struct
{
int i;
char ch;
double d;
}str1;
struct
{
int i;
double d;
char ch;
}str2;
main()
{
if (sizeof(str1) != sizeof(str2))
printf("不一样");
}
实验二:
struct
{
int i;
char ch;
double d;
}str;
void f(int i, char ch, double d)
{
printf("结构体:\n");
printf("%5d%5d%5d", &str.i-&str.i, &str.ch-&str, &str.d-&str);
printf("函数:");
printf("%5d%5d%5d", &i-&i, &ch-&i, &d-&i);
}
main()
{
f(0, 'a', 13.0);
}
通过实验一,发现str1和str2的大小不一样, 这就是参数要进行数据对齐, 对齐大小是好像是2字. 好像是, 但是从宏函数上可以知道对齐大小是sizeof(int)
然后从实验二, 发现函数参数的数据对齐和结构体数据对齐一样一样滴~
所以函数参数对齐也是按照结构体进行的.
我记得网上说的是4字(节)对齐.
对齐方法就是该变量的地址必须是在结构体中地址的4倍,
int, char, double
int是第一个, 它不用对齐, char因为前面是个int, 不用对齐, 它本身就是齐了的, 所以不用多用字节, 但是double, 它如果直接跟着char保存, 就不是对齐了, 因为int + char = 5所以要空出3字节空间, 然后第8字节当然double首地址, 所以int, char, double型保存要占16字节
而int double char只需要13字节.
好像说数据对齐有利于寻址.
解释并不难,但按字面解释是没有意义的。因为宏定义与主体代码紧密相关,没有主体代码就不知道宏参数n、v、t等的意思,就没有办法说清楚这些宏的目的。比如第一个,就是把“对象n所占内存大小与一个整型数据所占内存的大小减1,和一个整型数所占内存大小减1并取反后的‘逻辑与’”定义为标识符_INTSIZEOF(n)。以后在代码中需要表达上述双引号内的意思时,写标识符_INTSIZEOF(n)就可以了……
_INTSIZEOF的实际语义是“不小于参数 n 所占内存大小,且是 sizeof(int) 倍数的最小整数”,目的是把对齐考虑在内后获取参数 n 所占的内存。
比如
int f(char a,char b);
虽然sizeof(a)等于 1 ,但 b 的地址与 a 的地址之差(即&b - &a)可能等于 4 。实现 va_arg 的时候就要考虑这个方面
刨去 _INTSIZEOF 和把参数转换成合适的类型之外,其实这三个宏没什么特别的