格物致知 c语言字节数、对齐、补齐的小探索
写在前面
工作几年了,由于信奉陶渊明的
“好读书,不求甚解”
(其实是懒)
的思想,很多概念其实了解的很模糊,最近工作中遇到一个问题:“64位环境下,指针占多少个字节?”,信誓旦旦的回答了4个字节,说指针无论32位环境下还是64位环境下,均占4个字节。
结果,可以想象,测试结果悲剧了。。。
这里格物致知一下,写了几个小demo,清晰一下混淆了很久的概念。
注:这里仅提供32和64位环境的测试结果,其实还有16位等,环境不好找,暂时放弃。
基本数据类型字节数
32位环境下字节数
char | bool | short int | int | long int | long long int | float | double | ptr | struct ptr |
---|---|---|---|---|---|---|---|---|---|
1 | 1 | 2 | 4 | 4 | 8 | 4 | 8 | 4 | 4 |
64位环境下字节数
char | bool | short int | int | long int | long long int | float | double | ptr | struct ptr |
---|---|---|---|---|---|---|---|---|---|
1 | 1 | 2 | 4 | 8 | 8 | 4 | 8 | 8 | 8 |
上面的表格,已经描述了大部分的差异,这里进一步解释一下特殊情况:
- 上面的short int/long int/long long int中的int可以省略。
- c标准中,并没有强制规定short < int < long,而是short <= int <= long,因此并不是说int就一定是4个字节,实际上,某些资料上说,16位环境下sizeof(int) = sizeof(short) = 2。
- 对于指针来说,32位平台下,4字节,64位平台下,8字节。
有关心测试用例和测试结果的朋友可以看看下面。
#include <stdio.h> typedef struct tag_st
{ char b; short w; int dw;
} st; int main(int argc, char* argv[])
{ printf("char size = %d\n", sizeof(char)); printf("short size = %d\n", sizeof(short)); printf("int size = %d\n", sizeof(int)); printf("long size = %d\n", sizeof(long)); printf("long int size = %d\n", sizeof(long int)); printf("long long int size = %d\n", sizeof(long long int)); printf("float size = %d\n", sizeof(float)); printf("double size = %d\n", sizeof(double)); printf("ptr size = %d\n", sizeof(char*)); printf("struct ptr size = %d\n", sizeof(st*)); return 0;
}
32位平台结果
bennett@linux-hycc:~/WorkSpace/test> gcc test.c -o test -m32
bennett@linux-hycc:~/WorkSpace/test> ./test
char size = 1
bool size = 1
short int size = 2
int size = 4
long int size = 4
long long int size = 8
float size = 4
double size = 8
ptr size = 4
struct ptr size = 4
64位平台结果
bennett@linux-hycc:~/WorkSpace/test> gcc test.c -o test -m64
bennett@linux-hycc:~/WorkSpace/test> ./test
char size = 1
bool size = 1
short int size = 2
int size = 4
long int size = 8
long long int size = 8
float size = 4
double size = 8
ptr size = 8
struct ptr size = 8
结构体的对齐和补齐
默认情况
数据类型 | 默认对齐字节 |
---|---|
基本类型 | sizeof(基本类型) |
数组 | sizeof(单个成员) |
联合 | sizeof(最大成员) |
结构体 | sizeof(每个成员) |
对齐:
默认情况下,基本数据类型按照自身大小整数倍进行对齐,即每个成员的首地址应该是自身大小的整数倍。
- 特殊的,对于数组成员,按照每个成员的大小进行对齐;
- 对于联合,按照最大成员大小进行对齐;
- 对于结构体内包含结构体的,递归的按照结构体的对齐方式对齐。
数据类型 | 默认补齐字节 |
---|---|
基本类型 | min(max(sizeof(基本类型)), 4) |
补齐:
默认情况下,按照最大成成员大小进行补齐,对于超过4字节的,按照4字节补齐。
#include <stdio.h> typedef union tag_un
{ double ld1; double ld2; double ld3; double ld4;
} un; typedef struct tag_unn
{ short w; char b;
} unn; typedef struct tag_stt
{ double ld1; double ld2; double ld3;
} stt; typedef struct tag_sttt
{ char arr1[11]; short arr2[1];
} sttt; typedef struct tag_st
{ double ld; char arr1[2]; char *ptr; char b; short arr2[18]; un un; unn unn; stt stt;
} st;
int main(int argc, char* argv[])
{ st st = {0.0, "ab", NULL}; printf("struct st size = %d\n", sizeof(st)); printf("struct sttt size = %d\n", sizeof(sttt)); printf("ld address = %p\n", &st.ld);printf("arr1 address = %p\n", &st.arr1);printf("ptr address = %p\n", &st.ptr);printf("b address = %p\n", &st.b);printf("arr2 address = %p\n", &st.arr2);printf("un address = %p\n", &st.un);printf("unn address = %p\n", &st.unn);printf("stt address = %p\n", &st.stt);return 0;
}
执行结果如下:
32位平台:
bennett@linux-hycc:~/WorkSpace/test> gcc test.c -o test -m32
bennett@linux-hycc:~/WorkSpace/test> ./test
struct st size = 92
struct sttt size = 14
ld address = 0xff962210
arr1 address = 0xff962218
ptr address = 0xff96221c
b address = 0xff962220
arr2 address = 0xff962222
un address = 0xff962248
unn address = 0xff962250
stt address = 0xff962254
64位平台:
bennett@linux-hycc:~/WorkSpace/test> gcc test.c -o test -m64
bennett@linux-hycc:~/WorkSpace/test> ./test
struct st size = 104
struct sttt size = 14
ld address = 0x7ffc512757c0
arr1 address = 0x7ffc512757c8
ptr address = 0x7ffc512757d0
b address = 0x7ffc512757d8
arr2 address = 0x7ffc512757da
un address = 0x7ffc51275800
unn address = 0x7ffc51275808
stt address = 0x7ffc51275810
编译器命令
#pragma pack(n)
对齐:
数据类型 | 默认对齐字节 |
---|---|
基本类型 | min(sizeof(基本类型), n) |
数组 | min(sizeof(单个成员), n) |
联合 | min(sizeof(最大成员), n) |
结构体 | min(sizeof(每个成员), n) |
补齐:
数据类型 | 默认补齐字节 |
---|---|
基本类型 | min(max(sizeof(基本类型)), n) |
写在结尾
想着好好写来的,结果用例的名字还是乱七八糟,暂时不改了,有机会再调整吧。
格物致知 c语言字节数、对齐、补齐的小探索相关推荐
- c语言字节强制对齐,C语言的那些小秘密之字节对齐
为了让读者加深印象,我们这里在代码中没有使用0,而是使用的4,所以在最终计算出的结果部分减去了一个4才是偏移地址,当然实际使用中我们都是用的是0. 懂了上面的宏offsetof之后我们再来看看下面的代 ...
- 点阵c语言字节数,用C语言编程16点阵字库!
程序如下,只要说明各函数模块的功能即可: #include #include #include #include #include #include #include #define GETADR(n ...
- C语言字节对齐规则总结
原始链接源自 https://www.cnblogs.com/clover-toeic/p/3853132.html , 从上面博客中学习总结得到下面的文章. 不同硬件平台,对存储空间的处理不一样,比 ...
- 程序人生 | C语言字节对齐问题详解 - 对齐/字节序/位序/网络序等(上)
本文首发于 2014-07-21 15:32:28 1. 引言 考虑下面的结构体定义: typedef struct{char c1;short s; char c2; int i; }T_FOO; ...
- C语言字节对齐问题详解
转载原文连接:https://www.cnblogs.com/clover-toeic/p/3853132.html C语言字节对齐问题详解 引言 考虑下面的结构体定义: 1 typedef stru ...
- C语言字节对齐问题详解(zz)
http://www.bubuko.com/infodetail-263205.html 引言 考虑下面的结构体定义: typedef struct{char c1;short s; char c2; ...
- c语言特殊字符字符串宽度对齐,[转]C语言字节对齐问题详解
引言 考虑下面的结构体定义: 1 typedef struct{2 charc1;3 shorts;4 charc2;5 inti;6 }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1 ...
- C语言 printf 格式化 输出 右对齐补零
C语言IO--printf右对齐补零 关于printf的一点总结,内容来自http://blog.sina.com.cn/s/blog_5ac88b350100auna.html 1.1 标准输入输 ...
- c语言中的字节序和字节对齐,C语言字节序对齐以及空间利用率
环境:ubuntu 64bit gcc vim #include #include #include #include #include #include #include typedef struc ...
最新文章
- Learn OpenGL (十二):投光物
- dpi shell命令 安卓_android 中 dumpsys 命令使用
- NTU商汤提出新 loss!提升图像重建和图像合成的质量 (ICCV2021)
- 数据中心备受关注的三大方面
- 侧滑抽屉菜单 FlowingDrawer
- struts 的 MVC ,自己堆栈跟踪(可以跟着做一遍)
- 机器学习(十)——因子分析
- mysql dump 表数据 shell 脚本
- 【重点】剑指offer——面试题53:正则表达式匹配
- mac修改文件的默认打开方式
- Thinkphp在Nginx服务器下部署的问题--宝塔面板篇
- activity(工作流)初步学习记录
- JVM-运行时数据区:Java堆(Heap) 内存管理的核心区
- CSDN-markdown编辑器的使用
- 凛冬的寒风,吹开了电动车的遮羞布
- linux内核中的copy_to_user和copy_from_user(一)
- 最新猫眼电影反爬虫解密
- 互联网日报 | 2月24日 星期三 | 华为去年收入利润保持正增长;特斯拉公开全国统一维保价目表;途虎养车回应赴美上市传闻...
- 【剑指 Java】第 1 弹:靠这份 Java 基础知识总结,我拿到了满意的 Offer
- c语言程序设计教程博客,嵌入式C语言教程以及C编程要素
热门文章
- PCB应力应变测试-ICT、FCT治具应力把控标准
- sel2000服务器自动关闭,管家婆辉煌:轻松处理SQL 2000数据库自动停止
- 杭电多校第六场个人补题6 7 9 10 12
- 云呐容灾备份策略,存储容灾备份系统
- 用ps做个一寸的照片
- Dell服务器网卡驱动升级[CentOS 5.5 X86_64和RHEL 5.6 X86_64]
- 重磅!人工智能会取代科学家? 道翰天琼认知智能机器人API接口平台为您揭秘-1。
- PDPS软件:机器人示教编程与工作站仿真运行
- 怎样在电脑上录制ppt课件?如何录制课件讲解视频
- 雷电2接口_雷电3和Type-C接口一样吗?差别很大