說明結構變量有以下三種方法。以上面定義的stu為例來加以說明。 1. 先定義結構,再說明結構變量。如: struct stu { int num; char name[20]; char sex; float score; }; struct stu boy1,boy2; 說明了兩個變量boy1和boy2為stu結構類型。也可以用宏定義使一個符號常量來表示一個結構類型,例如: #define STU struct stu STU { int num; char name[20]; char sex; float score; }; STU boy1,boy2;
2. 在定義結構類型的同時說明結構變量。例如: struct stu { int num; char name[20]; char sex; float score; }boy1,boy2;
在圖7.3中,第0個結點稱為頭結點, 它存放有第一個結點的首地址,它沒有數據,只是一個指針變量。 以下的每個結點都分為兩個域,一個是數據域,存放各種實際的數據,如學號num,姓名name,性別sex和成績score等。另一個域為指針域, 存放下一結點的首地址。鏈表中的每一個結點都是同一種結構類型。例如, 一個存放學生學號和成績的結點應為以下結構: struct stu { int num; int score; struct stu *next; } 前兩個成員項組成數據域,后一個成員項next構成指針域, 它是一個指向stu類型結構的指針變量。鏈表的基本操作對鏈表的主要操作有以下幾種: 1.建立鏈表; 2.結構的查找與輸出; 3.插入一個結點; 4.刪除一個結點; 下面通過例題來說明這些操作。 [例7.10]建立一個三個結點的鏈表,存放學生數據。 為簡單起見, 我們假定學生數據結構中只有學號和年齡兩項。 可編寫一個建立鏈表的函數creat。程序如下: #define NULL 0 #define TYPE struct stu #define LEN sizeof (struct stu) struct stu { int num; int age; struct stu *next; }; TYPE *creat(int n) { struct stu *head,*pf,*pb; int i; for(i=0;i<n;i++) { pb=(TYPE*) malloc(LEN); printf("input Number and Age/n"); scanf("%d%d",&pb->num,&pb->age); if(i==0) pf=head=pb; else pf->next=pb; pb->next=NULL; pf=pb; } return(head); } 在函數外首先用宏定義對三個符號常量作了定義。這里用TYPE表示struct stu,用LEN表示sizeof(struct stu)主要的目的是為了在以下程序內減少書寫并使閱讀更加方便。結構stu定義為外部類型,程序中的各個函數均可使用該定義。
[例7.11]寫一個函數,在鏈表中按學號查找該結點。 TYPE * search (TYPE *head,int n) { TYPE *p; int i; p=head; while (p->num!=n && p->next!=NULL) p=p->next; /* 不是要找的結點后移一步*/ if (p->num==n) return (p); if (p->num!=n&& p->next==NULL) printf ("Node %d has not been found!/n",n } 本函數中使用的符號常量TYPE與例7.10的宏定義相同,等于struct stu。函數有兩個形參,head是指向鏈表的指針變量,n為要查找的學號。進入while語句,逐個檢查結點的num成員是否等于n,假如不等于n且指針域不等于NULL(不是最后結點)則后移一個結點,繼續循環。如找到該結點則返回結點指針。 如循環結束仍未找到該結點則輸出“未找到”的提示信息。
[例7.12]寫一個函數,刪除鏈表中的指定結點。刪除一個結點有兩種情況: 1. 被刪除結點是第一個結點。這種情況只需使head指向第二個結點即可。即head=pb->next。其過程如圖7.5所示。 2. 被刪結點不是第一個結點,這種情況使被刪結點的前一結點指向被刪結點的后一結點即可。即pf->next=pb->next。其過程如圖7.6所示。 函數編程如下: TYPE * delete(TYPE * head,int num) { TYPE *pf,*pb; if(head==NULL) /*如為空表, 輸出提示信息*/ { printf("/nempty list!/n"); goto end;} pb=head; while (pb->num!=num && pb->next!=NULL) /*當不是要刪除的結點,而且也不是最后一個結點時,繼續循環*/ {pf=pb;pb=pb->next;}/*pf指向當前結點,pb指向下一結點*/ if(pb->num==num) {if(pb==head) head=pb->next; /*如找到被刪結點,且為第一結點,則使head指向第二個結點, 否則使pf所指結點的指針指向下一結點*/ else pf->next=pb->next; free(pb); printf("The node is deleted/n");} else printf("The node not been foud!/n"); end: return head; } 函數有兩個形參,head為指向鏈表第一結點的指針變量,num刪結點的學號。 首先判定鏈表是否為空,為空則不可能有被刪結點。若不為空,則使pb指針指向鏈表的第一個結點。進入while語句后逐個查找被刪結點。找到被刪結點之后再看是否為第一結點,若是則使head指向第二結點(即把第一結點從鏈中刪去),否則使被刪結點的前一結點(pf所指)指向被刪結點的后一結點(被刪結點的指針域所指)。如若循環結束未找到要刪的結點, 則輸出“末找到”的提示信息。最后返回head值。