用了多年的c, sizeof几乎没怎么用过, 一直蒙查查的, 今天查了一下用法, 发现忽视了不知识呢,
预备知识:
- char c='a' 与 'a',c是1字节的字符变量, 但'a'是占4字节的整形常量;
- char *c, c是地址, 指向的数据按1字节读取, 但c本身是指针类型, 无符号整型(u32), 用4字节存放的地址值;
- 字节对齐, 内存为了高速地处理数据, 每次按32位读写, 数据存放时地址自动调整在能被对齐字节数整除的位置.
sizeof ( x )
关键字, 关键字, 关键字, 不是函数 !
在编译时确定其值, 计算出x在内存中所占字节数.
所以, 括号内的赋值和函数, 不会被执行, 编译与执行, 没一分钱联系.
1. sizeof ( 数值 )
char c=8;
int i=32;
printf("%ld", sizeof(c )); // 结果:1, 因为char就是1字节
printf("%ld", sizeof(c+i )); // 结果:4, i是4字节, 运算时c值被隐式转换成int, 运算值是4字节
printf("%ld", sizeof(c=c+i)); // 结果:1, 等同于(c), 编译时, 因为=不被执行, 所以=的右边只是个屁
2. sizeof ( 字符 )
// 小心, char和'a'在被=动作前, 是两个独立类型, 没关联
char c = 'a';
printf("%ld", sizeof(c)); // 结果:1, char类型是1字节
printf("%ld", sizeof('a'); // C结果:4,C++结果:1
// C99的标准, 'a'是整型字符常量,常量!常量!常量!被看成是int型, 所以占4字节。
// ISO C++的标准,'a'是字符字面量 ,被看成是char型,所以占1字节。
3. sizeof ( 字符串 )
printf("%ld", sizeof("abc"); // 结果:4,双引号会在尾部自动添加转义字符'\0',即数据0X00, 所以是4
// 双引号作用: (1)字符串尾部加0, (2)开辟内存空间, (3)提取地址
4. sizeof ( 数组 )
char a[50]="老师,早上好!";
printf("%ld", sizeof(p)); // 结果:50, 返回数组总字节大小
5. sizeof ( 指针 )
// 小心, 指针是地址, 指向某数据空间, 地址常是4字节.
char *p="老师,早上好!";
printf("%ld", sizeof(p); // 结果:4, 返回指针大小,指针本身就是一个无符号整型数. 不是所指向的内存空间的大小
// char *a[8], 在数组内存放8个地址, 8个*4字节=32字节, 而不是8个*1字节=8字节
6. sizeof ( 结构体 )
// 字节对齐,为快速处理数据,内存是按32位读取写的,而不是一字节一字节地读写
// 结构体的首地址自动对齐至能被对齐字节数大小所整除。
// 结构体每个成员在结构体内的偏移地址都是成员大小的整数倍,否则, 在前方填充byte。
// 结构体的总大小为结构体对齐字节数大小的整数倍
struct T1{
int a; // 成员随意位置
char b;
int c;
short d;
}t1;
printf("%ld", sizeof(t1); // 结果:16, 4+4+4+4
struct T2{
int a; // 合理安排成员位置
char b;
short d;
int c;
}t2;
printf("%ld", sizeof(t2); // 结果:12, 4+4+4, 设计结构时,调整成员的位置,可节省存储空间。
7. sizeof ( 函数 )
// 小心, 函数不执行
char Sum(int i, short s);
printf("%ld", sizeof(Hellow(32, 8)); // 结果:1, 只会判断返回类型的大小. 函数是不会执行的!
如有错误, 望请回复指正~~
文章参考资料:
(1): CSDN博主「王二车」的原创文章,原文链接:https://blog.csdn.net/TSZ0000/article/details/82868929
(2) 理一理字节对齐的那些事, 理一理字节对齐的那些事 - 知乎