The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer.If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
When applied to an operand that has type char, unsigned char,or signed char,(or a qualified version thereof) the result is 1. When applied to an operand that has array type, the result is the total number of bytes in the array.When applied to an operand that has structure or union type, the result is the total number of bytes in such an object,including internal and trailing padding.
#include <stdio.h>
struct b
{
float f;
int a[2];
char p;
};
int main(void)
{
printf("sizeof(struct(b))=%d\n",sizeof(struct b));
return 0;
}
于是计算一下其大小:
= (sizeof(float)) + 2*(sizeof(int)) + (sizeof(char))
=4+2*4+1
=4+8+1
=13
而打印结果却是16!很显然13不等于16。
为什么呢?
在网上问了问高手,这里设计到编译器的字节对齐(编译器自动优化),在计算机处理数据过程中,由于内存的容量已经比较大了,所以编译器们通常考虑到了执行速度的优化,让程序尽可能快的访问内存。现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问 一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对 数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那 么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。
其实字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:
1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2)结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;例如上面第二个结构体变量的地址空间。
3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。例如上面第一个结构体变量。
综上所诉:在结构体b中char类型的p只占1个字节,而编译器会在其后面加上3的填充字节,所以该结构的大小就是16了。
加入把结构体定义为:
struct
{
float f;
int a[2];
char p,q,r;
}
其结果还是16哦!~大家不妨试试。