1.結構體
void test1()
{
typedef struct
{
int i;
}s;
typedef struct
{
char c1;//1
char c2;//1
int i;//4
}s1;//8
typedef struct
{
char c1;//1
int i;//4
char c2;//1
}s2;//12
typedef struct
{
char c2;//1
double d;//8
int i;//4
}s3;//24
typedef struct
{
char c1;//1
s s;//4
double i;//8
}s8;//16
typedef struct
{
char c1;//1
s1 s1;//8
int i;//4
}s4;//16
typedef struct
{
char c1;//1
s3 s3;//24
int i;//4
}s7;//40
/*typedef struct
{
char c1;//1
int i;//4
s3 s3;//24
}s7;//32*/
printf("s->%d\n", sizeof(s));
printf("s1->%d\n", sizeof(s1));
printf("s2->%d\n", sizeof(s2));
printf("s3->%d\n", sizeof(s3));
printf("s4->%d\n", sizeof(s4));
printf("s7->%d\n", sizeof(s7));
printf("s8->%d\n", sizeof(s8));
printf("char->%d\n", sizeof(char));//1
printf("short->%d\n", sizeof(short));//2
printf("int->%d\n", sizeof(int));//4
printf("long->%d\n", sizeof(long));//4
printf("char*->%d\n", sizeof(char*));//4
printf("double->%d\n", sizeof(double));//8
printf("long long->%d\n", sizeof(long long));//8
/*typedef struct node
{
int data;
node* next;//必須加上struct,此時還沒重命名
}node;*/
/*typedef struct node
{
int data;
struct node* next;
}node;*/
/*struct node
{
int data;
struct node next;//不能直接包含自身,引發遞歸定義了/
};*/
/*typedef struct stu//(不聲明時爲匿名結構體)
{
int data;
}s7;*///重命名
//s1 s2;//重命名
//struct stu s2;
/* struct stu//(不聲明時爲匿名結構體)
{
int data;
}s5;//定義一個自定義類型的變量
s5.data;*/
/*struct //(不聲明時爲匿名結構體)
{
int data;
}s6;
s6.data;*/
}
1.結構體是一個自定義類型,內部數據類型獨有內存空間,和聯合體(共用體要做好區分)。
2.計算機結構體大小需要內存對齊,爲什麼需要內存對齊呢?
由於32位處理器一次可以取出32個比特位(4字節),所以取數據的時候不是一個字節一個字節的取,如果數據類型小於4字節的話,會取出來然後分割,而且如果數據連續存儲,就會更加麻煩,所以引入內存對齊,以空間換時間。
3.如何進行內存對齊?
默認對齊數(win 8,linux 4)#pragma pack(n) n=1 2 4 8 16
第一位默認0開始
之後的數據要對齊,對齊數=min(默認對齊數,當前數據大小)
結構體總大小爲最大對齊數的整數倍。
嵌套了結構體的話(不能自引用,指針除外),總大小爲最大對齊數的整數倍(max(結構體,數據類型)),詳情留意s3 s4 s8,s7計算。
2.位域
void test2()
{
struct A
{
int _b : 5;//4
int _c : 4;//4
};//4
struct B
{
char _a : 3;
char _b : 4;//1
char _c : 5;//2
int _d : 5;//4
};//8
struct C
{
char _a : 3;
char _b : 4;//1
char _c1 : 5;//2
char _c2 : 5;//3
char _c3 : 5;//4
char _c4 : 5;//5
int _d : 5;//9
};//12
printf("%d\n",sizeof(struct A));//4
printf("%d\n", sizeof(struct B));//8
printf("%d\n", sizeof(struct C));//12
}
位域是控制類型所佔的比特位。(char 不能大於8,int不能大於32),小於該類型的比特位可以拼接。
也會存在內存對齊,對齊爲最大類型的整數倍,參見B,C.
3.聯合體
void test3()
{
union un1
{
char c;
int i;
}u1;
union un2
{
char c[5];
int i;
}u2;
printf("%d\n", sizeof(u1));//4
printf("%d\n", sizeof(u2));//8
u1.i = 1;
if (u1.c == 1)
{
printf("小端機\n");
}
else
{
printf("大端機\n");
}
printf("%d\n", sizeof(u1));
}
聯合體成員共用一塊內存,大小爲最大數據類型,適用於不常同時出現的數據,有利於節省內存空間。
我們可以通過賦值來驗證這個,同時可以通過這個方法,來驗證大小端。
同時聯合體也會內存對齊,u2的最大爲5,但是最大對齊數爲4,所以要對齊爲8.
4.枚舉類型
void test4()
{
enum day
{
HOUR,
MINUTE,//遞推
SECOND=5,//可以給數據大小
};
printf("%d\n", HOUR);
printf("%d\n", MINUTE);
printf("%d\n", SECOND);
}
枚舉類型常量,和宏的區別
1.可讀性好。
2.有類型檢查,安全,便於調試。
3.封裝性好,防止命名污染。
4.使用方便,可以一次定義好幾個,同時遞推數據大小,默認從0開始,也可以自己給值。
int main()
{
//test1();//結構體
//test2();//位段(位域)
//test3();//聯合體共用內存空間,大小爲數據類型大的所佔的空間。
//test4();//枚舉常量
system("pause");
return 0;
}
通過這個整理,我對聯合體,結構體,枚舉類型,位段有了新的理解,初學如果有錯誤,歡迎大家指正。