[C] C語言sizeof詳解 - 全部型別
阿新 • • 發佈:2018-12-02
VC++6.0環境
文章目錄
總結
- union看最大
- 找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
巨集的情況下
- 資料成員對齊
- struct的資料成員,第一個資料成員放在offset為0的地方
- 之後的每個資料成員儲存的起始位置要從該成員大小的整數倍開始
- 結構體作為成員
- 一個結構體裡同時包含結構體成員,則結構體成員要從其內部最大元素大小的整數倍地址開始儲存
- 結構體的總大小:即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】表示幾個變數共用一個記憶體位置,在不同的時期儲存不同的資料型別和不同長度的變數
【原則】
- 所有的共用體成員共用一個空間,並且同一時間只能儲存其中一個成員變數的值
- 當一個共用體被宣告時,編譯程式自動地產生一個變數,其長度為聯合中型別最大的變數長度的整數倍,且要≥其最大成員所佔的儲存空間
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