自定義型別

qq_46804966發表於2020-11-22

1.結構體

結構體的宣告

1.普通結構體

struct tag
{
    member-list;
}variable-list;

2.匿名結構體

struct 
{
	int a;
	char b;
	float c;
}x;

結構的自引用

struct Node
{
	int data;
	struct Node * next;
}

結構體變數的定義和初始化

1.普通結構體定義和初始化

struct Point
{
	int x;
	int y;
}p1;//p1為結構體型別的變數
struct Point p2; //定義結構體變數p2
struct Point p3 = {2,3};//初始化結構體變數

2.巢狀結構體定義和初始化

struct Node
{
	int data;
	struct Point p;
	struct Node * next;
}n1 = {10,{4,5},NULL};

結構體記憶體對齊

1.為什麼要記憶體對齊
如果不記憶體對齊,因為硬體平臺的限制,進而訪存次數增加,進而降低效率
2.什麼是記憶體對齊
通過犧牲空間的方法來換取效率的提升叫做記憶體對齊
3.記憶體對齊的原則
(1)第一個元素不需要對齊,直接存放
(2)其他成員變數要對齊(指的是起始偏移量能夠整除對齊數)到某個數字(對齊數)的整數倍的地址數
(3)結構體的總大小為最大對齊數的整數倍
(4)如果巢狀了結構體的情況,巢狀的結構體要對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍

修改預設對齊

1.#pragma pack(2),修改預設對齊位元組數為2,對齊數取2與結構體變數對齊數的較小值
2.#pragma pack(),取消設定的預設對齊數,還原為預設

2.位段

1.什麼是位段

1.位段的成員可以是int,unsigned int或signed int
2.位段的成員名後邊有一個冒號和一個數字

2.例項

struct A
{
	int _a:2;
	int _b:5;
	int _c:10;
	int _d:30;
};
//printf("%d\n",sizeof(struct A)); 2
#include<stdio.h>

#define MAX_SIZE A+B
struct _Record_Struct
{
	unsigned char Env_Alarm_ID : 4;
	unsigned char Para1 : 2;
	unsigned char state;
	unsigned char avail : 1;
	
}*Env_Alarm_Record;

int main()
{
	printf("%d\n",(sizeof(struct _Record_Struct) )); //3
	return 0;
}

執行結果:
3

3.列舉

1.{ }中存放的是列舉常量
2.預設從0開始,依次增1

列舉的優點

1.增加程式碼的可讀性和可維護性
2.和#define定義的識別符號比較,列舉有型別檢查,更加嚴謹
3.防止了命名汙染
4.便於除錯
5.使用方便,可以一次定義多個變數

4.聯合

1.聯合的成員是共同用同一塊記憶體空間
2.聯合體的大小至少是最大成員的大小
3.當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的整數倍

示例

#include<stdio.h>

union Un
{
	int i;
	char c;
};
union Un un;

int main()
{
	printf("%p\n", &(un.c));
	printf("%p\n", &(un.i));
	return 0;
}

執行結果:
00C1A13C
00C1A13C

判斷大小端

#include<stdio.h>

int main()
{
	union Un
	{
		int i;
		char c;
	};
	union Un un;
	un.i = 1;
	printf("%d\n", un.c);
	return 0;
}

執行結果:
1

相關文章