写在前面

工作几年了,由于信奉陶渊明的

“好读书,不求甚解”

(其实是懒)
的思想,很多概念其实了解的很模糊,最近工作中遇到一个问题:“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

上面的表格,已经描述了大部分的差异,这里进一步解释一下特殊情况:

  1. 上面的short int/long int/long long int中的int可以省略。
  2. c标准中,并没有强制规定short < int < long,而是short <= int <= long,因此并不是说int就一定是4个字节,实际上,某些资料上说,16位环境下sizeof(int) = sizeof(short) = 2。
  3. 对于指针来说,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(每个成员)

对齐:

默认情况下,基本数据类型按照自身大小整数倍进行对齐,即每个成员的首地址应该是自身大小的整数倍。

  1. 特殊的,对于数组成员,按照每个成员的大小进行对齐;
  2. 对于联合,按照最大成员大小进行对齐;
  3. 对于结构体内包含结构体的,递归的按照结构体的对齐方式对齐。
数据类型 默认补齐字节
基本类型 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语言字节数、对齐、补齐的小探索相关推荐

  1. c语言字节强制对齐,C语言的那些小秘密之字节对齐

    为了让读者加深印象,我们这里在代码中没有使用0,而是使用的4,所以在最终计算出的结果部分减去了一个4才是偏移地址,当然实际使用中我们都是用的是0. 懂了上面的宏offsetof之后我们再来看看下面的代 ...

  2. 点阵c语言字节数,用C语言编程16点阵字库!

    程序如下,只要说明各函数模块的功能即可: #include #include #include #include #include #include #include #define GETADR(n ...

  3. C语言字节对齐规则总结

    原始链接源自 https://www.cnblogs.com/clover-toeic/p/3853132.html , 从上面博客中学习总结得到下面的文章. 不同硬件平台,对存储空间的处理不一样,比 ...

  4. 程序人生 | C语言字节对齐问题详解 - 对齐/字节序/位序/网络序等(上)

    本文首发于 2014-07-21 15:32:28 1. 引言 考虑下面的结构体定义: typedef struct{char c1;short s; char c2; int i; }T_FOO; ...

  5. C语言字节对齐问题详解

    转载原文连接:https://www.cnblogs.com/clover-toeic/p/3853132.html C语言字节对齐问题详解 引言 考虑下面的结构体定义: 1 typedef stru ...

  6. C语言字节对齐问题详解(zz)

    http://www.bubuko.com/infodetail-263205.html 引言 考虑下面的结构体定义: typedef struct{char c1;short s; char c2; ...

  7. c语言特殊字符字符串宽度对齐,[转]C语言字节对齐问题详解

    引言 考虑下面的结构体定义: 1 typedef struct{2 charc1;3 shorts;4 charc2;5 inti;6 }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1 ...

  8. C语言 printf 格式化 输出 右对齐补零

    C语言IO--printf右对齐补零 关于printf的一点总结,内容来自http://blog.sina.com.cn/s/blog_5ac88b350100auna.html 1.1  标准输入输 ...

  9. c语言中的字节序和字节对齐,C语言字节序对齐以及空间利用率

    环境:ubuntu 64bit gcc vim #include #include #include #include #include #include #include typedef struc ...

最新文章

  1. Learn OpenGL (十二):投光物
  2. dpi shell命令 安卓_android 中 dumpsys 命令使用
  3. NTU商汤提出新 loss!提升图像重建和图像合成的质量 (ICCV2021)
  4. 数据中心备受关注的三大方面
  5. 侧滑抽屉菜单 FlowingDrawer
  6. struts 的 MVC ,自己堆栈跟踪(可以跟着做一遍)
  7. 机器学习(十)——因子分析
  8. mysql dump 表数据 shell 脚本
  9. 【重点】剑指offer——面试题53:正则表达式匹配
  10. mac修改文件的默认打开方式
  11. Thinkphp在Nginx服务器下部署的问题--宝塔面板篇
  12. activity(工作流)初步学习记录
  13. JVM-运行时数据区:Java堆(Heap) 内存管理的核心区
  14. CSDN-markdown编辑器的使用
  15. 凛冬的寒风,吹开了电动车的遮羞布
  16. linux内核中的copy_to_user和copy_from_user(一)
  17. 最新猫眼电影反爬虫解密
  18. 互联网日报 | 2月24日 星期三 | 华为去年收入利润保持正增长;特斯拉公开全国统一维保价目表;途虎养车回应赴美上市传闻...
  19. 【剑指 Java】第 1 弹:靠这份 Java 基础知识总结,我拿到了满意的 Offer
  20. c语言程序设计教程博客,嵌入式C语言教程以及C编程要素

热门文章

  1. PCB应力应变测试-ICT、FCT治具应力把控标准
  2. sel2000服务器自动关闭,管家婆辉煌:轻松处理SQL 2000数据库自动停止
  3. 杭电多校第六场个人补题6 7 9 10 12
  4. 云呐容灾备份策略,存储容灾备份系统
  5. 用ps做个一寸的照片
  6. Dell服务器网卡驱动升级[CentOS 5.5 X86_64和RHEL 5.6 X86_64]
  7. 重磅!人工智能会取代科学家? 道翰天琼认知智能机器人API接口平台为您揭秘-1。
  8. PDPS软件:机器人示教编程与工作站仿真运行
  9. 怎样在电脑上录制ppt课件?如何录制课件讲解视频
  10. 雷电2接口_雷电3和Type-C接口一样吗?差别很大