[C] C语言sizeof详解 - 全部类型

VC++6.0环境

总结

  1. union看最大
  2. 找struct最大的基础数据类型,每个成员变量都要与它对齐,最终结果一定要是它的倍数,而且至少要能把大家都存下

在这里插入图片描述

#include<stdio.h>
// 单位:字节(1字节=8位)


typedef struct _Point{
	double x;	// 8
	double y;	// 8
}POINT;	// 16

typedef struct _STRING{
	POINT start;	// 16
	POINT* next;	// 4
}STRING;	// 24:POINT内最大基础类型为double -> 要是8的整数 -> 24

#define MAX_POINT_SIZE 64
typedef struct _FIXED_POINTS{
	int npoint;	// 8:最大的基础数据类型为POINT内的double --> 要与8对齐
	POINT points[MAX_POINT_SIZE];	// 16*64
}FIXED_POINTS;	// 1032

struct _FLEX_POINTS{
	int npoint; // 4
	POINT* points; // 4:指针类型,就为4
}FLEX_POINTS; // 8

enum Color{one,two,three} enumTypeVar;


int GetArrayFirstSizeof(char *a) {
	return sizeof(a);
}



int main() {
	char c[50];
	// 基本类型
	printf(" -- 基本类型 --\n");
	printf("sizeof(char) = %d\n", sizeof(char) );	// 1
	printf("sizeof(short) = %d\n", sizeof(short) ); // 2
	printf("sizeof(int) = %d\n", sizeof(int) );		// 4
	printf("sizeof(long) = %d\n", sizeof(long) ); // 4
	printf("sizeof(float) = %d\n", sizeof(float) );	// 4
	printf("sizeof(double) = %d\n", sizeof(double) );	// 8
	
	// 指针
	printf(" -- 指针 --\n");
	printf("sizoef(int*) = %d\n", sizeof(int*) );	// 4
	printf("sizeof(void*) = %d\n", sizeof(void*) );	// 4
	printf("sizeof(char*) = %d\n", sizeof(char*) );	// 4
	printf("sizeof(char **) = %d\n", sizeof(char **) ); // 二级指针:指向指针的指针,还是4
	
	// 数组
	printf(" -- 数组 --\n");
	printf("△ char c[50] sizeof(c) = %d\n", sizeof(c) ); //数组首地址(数组名):数组所占空间的大小 50*sizeof(char)
	printf("△ char c[50] sizeof(&c[0]) = %d\n", sizeof(&c[0]) ); //数字首个元素的地址:指针大小4
	printf("△ char c[50] sizeof(&c[1]) = %d\n", sizeof(&c[1]) ); //数字第二个元素的地址:指针大小4
	printf("△ char c[50] GetArrayFirstSizeof(c) = %d\n", GetArrayFirstSizeof(c) ); //数组首地址传入函数:当成指针来传 -> 指针大小4
	
	// enum
	printf("△ enumTypeVar = %d\n", sizeof(enumTypeVar)); //当成整数存储:4

	// 结构体
	printf(" -- 结构体 --\n");
	printf("sizeof(POINT) = %d\n", sizeof(POINT) );	
	printf("sizeof(STRING) = %d\n", sizeof(STRING) );
	printf("sizeof(FIXED_POINTS) = %d\n", sizeof(FIXED_POINTS) );
	printf("sizeof(FIEX_POINTS) = %d\n", sizeof(FLEX_POINTS) );
	return 0;
}

结构体struct

【原则】没有#pragma pack宏的情况下

  1. 数据成员对齐
    • struct的数据成员,第一个数据成员放在offset为0的地方
    • 之后的每个数据成员存储的起始位置要从该成员大小的整数倍开始
  2. 结构体作为成员
    • 一个结构体里同时包含结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储
  3. 结构体的总大小:即sizeof的结果
    • 在按之前的对齐原则计算出来的大小的基础上,必须还得是其内部最大成员的整数倍,不足要补齐
typedef struct bb {
	int id;             //[0]....[3] 表示4字节
	double weight;      //[8].....[15]      原则1
	float height;      //[16]..[19],总长要为8的整数倍,仅对齐之后总长为[0]~[19]为20,补齐[20]...[23]     原则3
}BB;
typedef struct aa  {  	
	int  id;         //[0]...[3]          原则1 
	double score;     //[8]....[15]     
	short grade;    //[16],[17]         
	BB b;             //[24]......[47]       原则2(因为BB内部最大成员为double,即8的整数倍开始存储) 
	char name[2]; //[48][49]
}AA; 
cout<<sizeof(AA)<<" "<<sizeof(BB)<<endl; //输出结果:56 24

联合union

【union】表示几个变量共用一个内存位置,在不同的时期保存不同的数据类型和不同长度的变量

【原则】

  1. 所有的共用体成员共用一个空间,并且同一时间只能存储其中一个成员变量的值
  2. 当一个共用体被声明时,编译程序自动地产生一个变量,其长度为联合中类型最大的变量长度的整数倍,且要≥其最大成员所占的存储空间
union foo{
	char s[10]; // 10
	int i; // 4
}; // 12 : 规则2,最大类型为int,所以要为4的整数倍
union mm{
	char a; //1
	int b[5]; //20
	double c; //8
	int d[3]; //12
}; // 24:规则2,最大类型为double,所以要为8的整数倍

union与struct混合

【union中有struct】

struct inner{
	char c1; //[0] (补齐[1] [2] [3] [4] [5] [6] [7])
	double d; //[8] [9] ... [16]
	char c2; //[17] (补齐[18] ... [23])
}; //24:最大基础数据类型为double,每个成员都要与8对齐)
union data4{
	struct inner t1; //24
	int i; //4
	char c; //1
}; //24:基本数据类型为double,8的倍数 ->24

【struct中有union】

typedef union{
	long i; //4
	int k[5]; //4*5=20
	char c; //1
}DATE; //20 :最大基本数据类型为long,为4的倍数 ->20
struct data{
	int cat; //[0] [1] [2] [3]
	char c; //[4] (补齐[5] [6] [7])
	DATE cow; // [8]...[28]:DATE最大成员为long,要在4的倍数开始存储
	char a[6]; // [29] ...[33]
	// 最大基础数据类型为long,与4补齐:[34] [35]
}; //36

参考文章

  1. https://blog.csdn.net/selinahuiling/article/details/9046403