C語言筆記——自定義型別

M-ordinary.發表於2020-11-26

自定義型別

typedef型別說明

一般形式:

typedef 型別說明符 識別符號;

例如:typedef int INTERGER;

typedef與define巨集的定義有相似之處,但實際上有明顯不同:

  • typedef在編譯階段有效,而define巨集的定義是預處理,發生在編譯之前;
  • typedef用來定義型別的別名,不只包含基本的資料型別,還包括自定義(如struct),課便於記憶且有一定的作用域;而define沒有作用域的限制,只要是之前預定義過的巨集,在以後的程式中都可以使用;
  • typedef作為型別的宣告語句是以分號“ ;”結尾的,而define巨集的定義通常不需要用標點結束。

結構體

結構體宣告

一般形式:

struct 結構體標誌
{
型別說明符 結構體成員名1;
型別說明符 結構體成員名2;

型別說明符 結構體成員名n;
}

例如:描述一個學生

struct Stu   
{ 
	char num[20];
	char name[20];
	int age;
	char sex[3];
}Stu;

結構體定義和引用

1.定義

兩種形式:

//說明結構的同時定義變數
struct Stu
{ 
	char num[20];
	char name[20];
	int age;
	char sex[3];
}s1,s2;
//先說明結構,後定義結構體變數
struct Stu
{ 
	char num[20];
	char name[20];
	int age;
	char sex[3];
};
struct Stu s1,s2;

2.初始化和引用

(1)初始化

struct Stu        //型別宣告
{
	char name[15];//名字
 	int age;      //年齡
};
struct Stu s = {"zhangsan", 20};//初始化
struct Node
{
 	int data;
 	struct Point p;
 	struct Node* next;
}n1 = {10, {4,5}, NULL}; //結構體巢狀初始化
struct Node n2 = {20, {5, 6}, NULL};//結構體巢狀初始化

(2)引用
一般格式:

結構體成員變數 . 成員變數
例如上述Stu引用age: s.age=21;

自引用:

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

3.結構體記憶體對齊
可以通過以下幾道題總結出規律:

//練習1:
struct S1
{
 	char a;   // 1 +(補3)
 	int b;    // 4
 	char c;   // 1 +(補3)
};
printf("%d\n", sizeof(struct S1));    //12
//練習2:
struct S2
{
 	char a;  //1 +(補1)
	char b;  //1 +(補1)
 	int i;    //4
};
printf("%d\n", sizeof(struct S2));  //8
//練習3:
struct S3
{
 	double d; // 8
 	char c;   // 2 +(補2)
 	int i;   // 4
};
printf("%d\n", sizeof(struct S3));  //16
  • 第一個成員在與結構體變數偏移量為0的地址處。
  • 其他成員變數要對齊到某個數字(對齊數)的整數倍的地址處。 對齊數 = 編譯器預設的一個對齊數 與 該成員大小的較小值。
  • 結構體總大小為最大對齊數(每個成員變數都有一個對齊數)的整數倍。

結構體的記憶體對齊是拿空間來換取時間的做法
因此,在設計結構體時,應讓佔用空間小的成員儘量集中在一起

預設對齊數:

#pragma pack(2) 預設對齊數2
#pragma pack() 取消設定的預設對齊數,還原為預設

4.位段

例如:

//位域(節省空間)
typedef struct text
{
	char a : 1;  
	char b : 1;
	char c : 1;
}text;
void main()
{
	printf("%d\n", sizeof(text)); // 1
}

在這裡插入圖片描述

開闢空間最小單位按照位元組,“ :1 ”代表佔用1位(從bit位角度),1個位元組8個bit。

1.位域不能跨位元組儲存
2.位域不能跨型別儲存

列舉

定義:

enum Color
{
	red,   //列舉用“ , ”分隔
	green,
	blue
};
void main()
{				
	printf("%d %d %d\n", red, green, blue);   //結果: 0 1 2  
	printf("size = %d \n", sizeof(enum Color));    //  4 
}    
  • 預設從零開始,依次加1,只能是整數;
  • 若有賦值,則賦值後依次加1;
  • 每次只能傳送一個;

聯合

聯合的成員是共用同一塊記憶體空間的,這樣一個聯合變數的大小,至少是最大成員的大小(因為聯合至少得有能力儲存最大的那個成員),當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的整數倍

union Un
{
	char c;
	int i;
};
void main()
{
	union Un un;
	printf("%d\n", sizeof(un));   //  4 (最大成員的大小)
}

可以用來判斷大小端:(大小端在“資料的儲存”有講)

//判斷大小端
union Un
{
	int a;
	char c;
};
void main()
{
	union Un un;
	un.a = 1;
	if (un.c == 1)
	{
		printf("little\n");
	}
	else printf("big\n");
}

相關文章