C/C++中sizeof的详细测试分析报告

以下数据来自于Dev CPP首先呈现实际测试数据:主程序如下:  1 #include string.h> 2 #include  3  4 using namespace std; 5  6 typedef struct s1 { 7 //char ch, *ptr; 8 union { 9 short a, b;10 //unsigned int c:2, d:1;11  
摘要由CSDN通过智能技术生成

以下数据来自于Dev CPP

首先呈现实际测试数据:

主程序如下:

 

 1 #include < string.h>
 2 #include <iostream>
 3 
 4  using  namespace std;
 5 
 6 typedef  struct s1 {
 7  // char ch, *ptr;
 8  union {
 9  short a, b;
10  // unsigned int c:2, d:1;
11      };
12 };
13  // struct s1 *next;
14  // };
15 
16  int main()
17 {
18     printf( " %d\n ", sizeof(s1));
19     system( " pause ");
20      return  1;
21 }

下面的测试数据,通过不断修改struct的结构体内容,来达到不同的测试结果。

 

1 typedef  struct s1 {
2  // char ch, *ptr;
3  union {
4  short a, b;
5  // unsigned int c:2, d:1;
6      };
7 };

以上测试样例一输出答案:2

 

1 typedef  struct s1 {
2  char ch, *ptr;
3  // union {
4  // short a, b;
5  // unsigned int c:2, d:1;
6  //     };
7  };

以上测试样例二输出答案:8

1 typedef  struct s1 {
2  char ch; // , *ptr;
3  // union {
4  // short a, b;
5  // unsigned int c:2, d:1;
6  //     };
7  };

以上测试样例三输出答案:1

1 typedef struct s1 {
2 char ch, *ptr;
3 union {
4 // short a, b;
5 // unsigned int c:2, d:1;
6 };
7 };

以上测试样例四输出结果:12

1 typedef  struct s1 {
2  char ch, *ptr;
3 union {
4  short a, b;
5  // unsigned int c:2, d:1;
6      };
7 };

以上测试样例五输出答案:12

1 typedef  struct s1 {
2  char ch, *ptr;
3 union {
4  short a, b;
5 unsigned  int c: 2, d: 1;
6     };
7 };

以上测试样例六输出答案:12

1 typedef  struct s1 {
2  // char ch, *ptr;
3  union {
4  short a, b;
5 unsigned  int c: 2, d: 1;
6     };
7 };

以上测试样例七输出答案:4

1 typedef  struct s1 {
2  // char ch, *ptr;
3  union {
4  // short a, b;
5  unsigned  int c: 2, d: 1;
6     };
7 };

以上测试样例八输出答案:4

1 typedef  struct s1 {
2  // char ch, *ptr;
3  union {
4  // short a, b;
5  // unsigned int c:2, d:1;
6      };
7 };

以上测试样例九输出答案:1

 

通过上述实验结果而知,首先对于32bits的PC来说,定义下:

char,uchar 1个字节

int uint 4个字节

union一个字节

上述是前提,供后续分析使用。

 

首先是字节对齐的问题,何为字节对齐?

个人认为字节对齐主要是因为两个方面的原因:

  1. 统一标准,进行不同设备间的通讯,比如:异构CPU,异构内存模型等等
  2. 加速数据的访问,字节对齐能使得取值,save等操作更加方便,因为存储时起始地址都是对齐后的地址。

那么非结构体时,无需考虑sizeof后的效果,因为原生态的类型,在存储时占用大小一致,只是原生态的变量间会有不同的填充空间。

 

下面只是分析结构体内的处理方式,下面是几个原则:

  1. 结构体对齐存在结构体内对齐,结构体对齐两个部分。
  2. 结构体内每个变量存放的其实地址必须是自己所用大小的整数倍。
  3. 结构体对齐需要结构体的长度是结构体内最大占用变量的长度的整数倍。
  4. union占用一个字节,内部变量共享所有的内存。

下面利用上述三个原则来重新分析下上述实验结果。

 

 

1 typedef struct s1 {
2 // char ch, *ptr;
3 union {
4 short a, b;
5 // unsigned int c:2, d:1;
6 };
7 };

 

以上测试样例一输出答案:2

union共享内存,也就是说a b两个变量共享内存,short在32bits机器中是双字节变量,所以长度为2;

结构体对齐:目前内部长度是2,内部最大变量也是2,所以是整数倍。不需要结构体对齐。最终结果是2;

 

1 typedef struct s1 {
2 char ch, *ptr;
3 // union {
4 // short a, b;
5 // unsigned int c:2, d:1;
6 // };
7 };

 

以上测试样例二输出答案:8

结构体内有两个变量,char char*

首先char型占用一个字节,char*指针占用四个字节。

指针需要从addr%4==0的地址开始,所以char---char*之间系统需要补充3个字节。

所以char+char*后的长度是8,最长的内部变量长度是char*=4个,所以满足结构体对齐,不需要结构体调整。

所以最终长度是8。

 

 

1 typedef struct s1 {
2 char ch; // , *ptr;
3 // union {
4 // short a, b;
5 // unsigned int c:2, d:1;
6 // };
7 };

 

以上测试样例三输出答案:1

简单的char是1个字节,结构体内长度=1,最长变量长度也是1,所以满足条件,无需结构体调整。

 

 

 

1 typedef struct s1 {
2 char ch, *ptr;
3 union {
4 // short a, b;
5 // unsigned int c:2, d:1;
6 };
7 };

 

以上测试样例四输出结果:12

char+char*后的长度是8,union长度默认是1,

所以长度应该是9,但是结构体内最大变量的长度是4,不满足addr%4==0,所以结构需要进行调整。

(9+x)%4==0的最小长度是12

所以程序输出为12;

 

 

1 typedef struct s1 {
2 char ch, *ptr;
3 union {
4 short a, b;
5 // unsigned int c:2, d:1;
6 };
7 };

以上测试样例五输出答案:12

char====1

填充====3个空白字节

char*===4

union====1(内部short===2,a b共用2个字节),所以union长度是max(union,short)==2;

结构体内长度:1+3+4+2=10;

不满足结构体长度%4==0;

所以需要进行调整,最终为12

 

 

1 typedef struct s1 {
2 char ch, *ptr;
3 union {
4 short a, b;
5 unsigned int c: 2, d: 1;
6 };
7 };

以上测试样例六输出答案:12

这个分析同上。

只是需要说明的是位域在union中也是当成一个单独的变量,共用最长变量的内存单元,unsigned int长度为4。

 

 

1 typedef struct s1 {
2 // char ch, *ptr;
3 union {
4 short a, b;
5 unsigned int c: 2, d: 1;
6 };
7 };

以上测试样例七输出答案:4

同上

 

 

1 typedef struct s1 {
2 // char ch, *ptr;
3 union {
4 // short a, b;
5 unsigned int c: 2, d: 1;
6 };
7 };

以上测试样例八输出答案:4

同上

 

 

1 typedef struct s1 {
2 // char ch, *ptr;
3 union {
4 // short a, b;
5 // unsigned int c:2, d:1;
6 };
7 };

以上测试样例九输出答案:1

原则性的条款,union默认长度是byte长度===1

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值