1. 程式人生 > >結構體和結構體連結串列

結構體和結構體連結串列

       在c語言錶針中有多種資料型別,他們的應用使變數的應用變得靈活多變。而除了c語言預設的int ,float ...等型別外,我們還可以自己定義一些資料的型別,結構體型別便是可以實現資料型別自定義的型別。

       結構體是一種型別,他的應用和int,float等變數型別的應用方法一致,切記,結構體是一種型別,不可當作變數進行使用。

       在結構體型別使用時要先進行結構體型別的定義。例如

#include<stdio.h>
struct student
{
	int num;
	char name[20];
	int score[3];
	int aver;
};

       這便是定義了一個結構體型別。結構體的定義必須應用struct關鍵詞,關鍵詞後緊跟著的是結構體名,然後在這個結構體中有四個成員,分別是 整形型別的變數num,字元型陣列 name[20],整形陣列 score[3], 整形型別變數aver,這就完成了一個結構體型別的定義。此時這個結構體型別是 struct student ,在應用時就以這個結構體型別來定義結構體變數。注意,結構體是型別,不是變數,不能直接應用,要定義一個結構體變數才能應用。換句話說,花了一個圖紙不等於蓋了一棟房子,圖紙還只是圖紙,仍舊需要磚瓦來蓋大樓。例如

#include<stdio.h>
	struct student
	{
		int num;
		char name[20];
		int age;
		int score;
	};
int main()
{
	struct student student1={0,name,0,0};
	struct student student2={0};
}

       在以上例子中,在main函式中定義了兩個結構體變數,分別是 student1 和 student2 ,他們的型別是struct student,這就完成了結構體變數的定義,再定義後可以進行初始化,例子中的花括號中的內容就是初始化的內容。如果只初始化了一部分內容,則剩餘的部分的結構體成員均被編譯器自動初始化為 0

       既然定義了一個結構體,那麼如何應用一個結構體呢?其實結構體變數的應用和我們平常所使用的變數沒有太大的區別,只是換了一種訪問的方式。例如

#include<stdio.h>
int main()
{
	struct stduent
	{
		int num;
		char name[20];
		int age;
		int score;
	};
	struct student student1={0,name,0,0};
	struct student student2={0};
	printf("Plase input stduent1:\n");
	scanf("%d%s%d%d", &stduent1.num, stduent1.name, &stduent1.age, &stduent1.score);
	printf("Plase input stduent2:\n");
	scanf("%d%s%d%d", &stduent2.num, stduent2.name, &stduent2.age, &stduent2.score);
	if (stduent1.score > stduent2.score)
	{
		printf("stduent1 :\n%d\n%s\n%d\n%d\n", stduent1.num, stduent1.name, stduent1.age, stduent1.score);
	}
	else if (stduent1.score < stduent2.score)
	{
		printf("stduent2 :\n%d\n%s\n%d\n%d\n", stduent2.num, stduent2.name, stduent2.age, stduent2.score);
	}
	else
	{
			printf("stduent1 :\n%d\n%s\n%d\n%d\n", stduent1.num, stduent1.name, stduent1.age, stduent1.score);
			printf("stduent2 :\n%d\n%s\n%d\n%d\n", stduent2.num, stduent2.name, stduent2.age, stduent2.score);
	}
	system("pause");
	return 0;
}

       這便是一個完整結構體應用的程式碼,目的是輸入兩個學生的學號,姓名,年齡和成績,然後比較兩個人的成績,然後輸出成績較高的同學的所有資訊。在結構體變數成員的訪問中需要用到的運算子是" . "該運算子可以對結構體變數成員進行訪問。

       既然結構體是一種型別,那麼就一定有結構體指標了。前面說過,結構體是一種型別,他的應用方法和c語言預設的資料型別的應用方法一致,因此,其它型別的的指標如何使用,結構體指標就如何使用。例如,定義一個結構體指標 p,將一個結構體變數的變數名賦給p,則此時p指向的是結構體的首地址,如果對想通過結構體指標p來訪問該結構體變數的成員,就需要進行節引用運算。方法如下

       1. (*p). 成員名

       2.    p  ->   成員名

       這兩種訪問的方式是等價的。

      以上便是結構體的解析。下面介紹連結串列以及結構體連結串列。

       連結串列,顧名思義,即是一條鏈狀的資料。連結串列是由一個 head 指標變數和許多節點組每個節點有許多元素,最後一個元素是一個指向下一個節點首地址的指標,第一個節點的首地址交給head,末尾的指標指向第二個節點的首地址,以此類推,到達最後一個節點,最後一個節點的末尾指標指向 NULL;這就是一條連結串列。一條連結串列必須有一個 head 指標才能尋找到第一個節點,否則無法進行連結串列的訪問,並且每個節點的末尾指標必須指向下一個節點的首地址,否則就無法進行鏈式訪問資料,並且最後一個節點的末尾指標必須指向NULL,避免指標指向未知區域。

       現在我們來建立一個專案,來實現一個連結串列的建立。首先,先定義一個節點結構體,這個結構體可以存放資料和末尾指標。

struct stduent
{
	long num;
	float score;
	struct stduent * next;
};

       然後在寫一個連結串列建立函式。

#define _CRT_SECURE_NO_WARNINGS 1
#define LEN sizeof(struct stduent)
#include<stdio.h>
#include<stdlib.h>
struct stduent
{
	long num;
	float score;
	struct stduent * next;
};
int n = 0;
struct stduent * creat(void)
{
	struct stduent * head = NULL;
	struct stduent * p1 = NULL;
	struct stduent * p2 = NULL;
	p1 = p2 = (struct stduent*)malloc(LEN);
	printf("請輸入索要儲存的學生學號和成績:\n");
	printf("如果需要退出請輸入 0 \n");
	printf("學號 成績\n");
	scanf("%ld,%f", &p1->num, &p1->score);
	while (p1->num != 0)
	{
		n += 1;
		if (n == 1)
		{
			head = p1;
		}
		else
		{
			p2->next = p1;
		}
			p2 = p1;
			p1 = (struct stduent *)malloc(LEN);
			printf("學號 成績\n");
			scanf("%ld,%f", &p1->num, &p1->score);
	}
	p2->next = NULL;
	return head;
}

       這時,一個連結串列建立函式已經建立完畢。在連結串列的建立過程中,通過動態記憶體開闢來實現空間的建立。如果輸入的num=0;

就表明連結串列建立完畢,結束建立。最後,再新增一個main函式就可以實現這個程式的運行了。

#define LEN sizeof(struct stduent)
#include<stdio.h>
#include<stdlib.h>
struct stduent
{
	long num;
	float score;
	struct stduent * next;
};
int n = 0;
struct stduent * creat(void)
{
	struct stduent * head = NULL;
	struct stduent * p1 = NULL;
	struct stduent * p2 = NULL;
	p1 = p2 = (struct stduent*)malloc(LEN);
	printf("請輸入索要儲存的學生學號和成績:\n");
	printf("如果需要退出請輸入 0 \n");
	printf("學號 成績\n");
	scanf("%ld,%f", &p1->num, &p1->score);
	while (p1->num != 0)
	{
		n += 1;
		if (n == 1)
		{
			head = p1;
		}
		else
		{
			p2->next = p1;
		}
			p2 = p1;
			p1 = (struct stduent *)malloc(LEN);
			printf("學號 成績\n");
			scanf("%ld,%f", &p1->num, &p1->score);
	}
	p2->next = NULL;
	return head;
}
int main()
{
	struct stduent*pt = NULL;
	pt = creat();
	if (pt!=NULL)
	{
		do
		{
			printf("%-4ld%4.1f\n", pt->num, pt->score);
			pt = pt->next;
		} while (pt != NULL);
	}
	system("pause");
	return 0;
}