結構(struct)
結 構 結構與陣列很類似,因為兩者都是將一些資料連接組合在一 起,以下為兩者的比較。 陣列 : 相同型態資料之集合. 結 構 結構與陣列很類似,因為兩者都是將一些資料連接組合在一 起,以下為兩者的比較。 陣列 : 相同型態資料之集合. 結構(struct) :可將不同型態的資料組合在一起 結構(struct)為結構(structure)的縮寫 結構中的項目通常稱為成員(member)。
結 構 宣 告 宣告一個結構的型態 宣告結構型 態的變數 結構的宣告(第一種) : struct 結構名稱 { 資料型態 欄位名稱1; 結 構 宣 告 結構的宣告(第一種) : struct 結構名稱 { 資料型態 欄位名稱1; 資料型態 欄位名稱2; . 資料型態 欄位名稱n; }; struct 結構名稱 變數1,變數2,…,變數m; 宣告一個結構的型態 宣告結構型 態的變數
結構宣告 範例 : struct mydata /* 定義結構mydata; declare the structure of mydata*/ { char name[8]; /* 各欄位的內容;the content of mydata */ char id[10]; int math; int eng; }; struct mydata student; /* 宣告結構mydata型態之變數student */
結 構 宣 告 – the Memory Space 上頁敘述會在記憶體裡配置空間出來讓 student 結構變數使用,記憶體的配置情況如下: 記憶體 name student id math 當結構被宣告後,每個結構成員所佔記憶體空間的大小視此 成員宣告的資料型態而定,例如,以上例而言: student.name佔了8bytes的記憶體空間, student.id佔了 9bytes的記憶體空間, student. math佔了2bytes的記憶體空間, student.eng佔了2bytes的記憶體空間,整個結構佔了21bytes的 記憶體空間。 eng
Example1---Test Memory Space #include<stdio.h> #include<stdlib.h> int main(void) { struct data char name[10]; char sex[2]; int math; }; struct data student; printf("sizeof(student)=%d\n",sizeof(student)); system("pause"); return 0; } 一個char佔1byte,陣列大小10,所以佔 10 byte
結 構 宣 告 – 續 若將結構型態與結構變數的宣告寫在同一個敘述中,就是第二種結構宣告。 struct 結構名稱 { 結 構 宣 告 – 續 若將結構型態與結構變數的宣告寫在同一個敘述中,就是第二種結構宣告。 struct 結構名稱 { 資料型態 欄位名稱1; 資料型態 欄位名稱2; . 資料型態 欄位名稱n; }變數1,變數2,…,變數m;
存取結構變數的成員 利用小數點(.)來存取結構變數中的成員。 結構變數名稱.成員名稱 例如: student.math = 90; student.eng = 20;
Example2 #include<stdio.h> int main(void) { struct mydata /* 定義並宣告結構變數 */ char name[15]; int math; }student; printf(" Student’s name: "); /* 輸入結構變數 */ gets(student.name); printf(" Math score: "); scanf("%d",&student.math); printf("*****Output*****\n"); /* 輸出結構變數內容 */ printf("%s’s Math score is %d\n",student.name,student.math); system("pause"); return 0; }
初值的設定 範例 : struct mydata /* 定義結構mydata */ { char name[15]; /* 各欄位的內容 */ char id[10]; int math; int eng; }; struct mydata student={“David Wang”,”411003”}; /* 宣告結構mydata型態之變數student,並設定結構內欄位的初值 */
Example3結構變數的初值設定 #include<stdio.h> int main(void) { struct data char name[10]; int math; }; struct data student={"Mary Wang",74}; printf("學生姓名:%s\n",student.name); printf("數學成績:%d\n",student.math); system("pause"); return 0; }
結構陣列 結構陣列 struct 結構名稱 結構陣列變數名稱[陣列大小]; [0] [1] … [14] [0] …. [9] .. 結構變數亦可以用宣告陣列,語法如下: struct 結構名稱 結構陣列變數名稱[陣列大小]; name id math eng [0] [1] … [14] Ex: struct student /* 定義結構mydata */ { char name[15]; /* 各成員(欄位)的內容 */ char id[10]; int math; int eng; }; struct student stu[3]; /*結構變數的宣告*/ [0] …. [9] math stu[0] eng stu[1] .. stu[2]
結構陣列---Example4 #include<stdio.h> #define MAX 2 int main(void) { int i; struct data /*定義結構data */ char name[10]; int math; }student[MAX]; for(i=0;i<MAX;i++) /*輸入結構陣列student的資料 */ printf("學生姓名:"); gets(student[i].name); printf("數學成績:"); scanf("%d",&student[i].math); fflush(stdin); /*清空緩衝區內的資料 */ } for(i=0;i<MAX;i++) /*輸出結構陣列的內容*/ printf("%s的數學成績=%d\n",student[i].name,student[i].math); system("pause"); return 0;
練習 請寫一個程式,定義一個結構,結構名稱為data 內含四個成員依序為, (1)姓名 (2)年齡 (3)電話 (4)血型 (變數名稱自訂) 內含四個成員依序為, (1)姓名 (2)年齡 (3)電話 (4)血型 (變數名稱自訂) 並且宣告3個學生(student)變數 使用者可以輸入上述四種資料,接著輸出於螢幕上。
結構指標 結構指標 struct 結構名稱 * 結構指標變數名稱; Ex: struct mydata /* 定義結構mydata */ { 結構變數也是指標的一種,只是它是指向此結構的指標,而非指向一般變數。 宣告格式如下: struct 結構名稱 * 結構指標變數名稱; Ex: struct mydata /* 定義結構mydata */ { char name[15]; /* 各成員(欄位)的內容 */ char id[10]; int math; int eng; } student; struct mydata * ptr; /*結構變數的宣告*/ ptr=&student; /*將指標指向此結構變數student*/
結構指標變數的使用 使用指標來存取結構變數內的成員(欄位)時,要利用「->」來連接欲存取的成員,如下 面格式: 結構指標名稱 -> 結構變數成員 Ex: ptr-> math即代表了指向結構變數student的math成員。 struct mydata/* 定義結構mydata */ { char name[15]; /* 各成員(欄位)的內容 */ char id[10]; int math; int eng; } student ; struct mydata * ptr; /*結構變數的宣告*/ ptr=&student; /*將指標指向此結構變數student*/
結構指標---Example5 #include<stdio.h> #include<stdlib.h> int main(void) { struct data char name[10]; int eng; }student; struct data *ptr; ptr=&student; printf("學生姓名:"); gets(ptr->name); printf("英文成績: "); scanf("%d",&ptr->eng); printf("英文成績=%d",ptr->eng); system("pause"); return 0; }
巢狀結構 結構可以存放不同的資料型態,所以在結構中也可以擁有另一個結構,如此就稱為巢狀結構(nested structure). 格式如下: { /*結構1的成員*/ }; struct 結構2 /*結構2的成員*/ struct 結構1 變數名稱; 定義巢狀結構
巢狀結構---Example6 #include<stdio.h> #include<stdlib.h> int main(void) { struct date /*define date*/ int month; int day; }; struct student /*define nested structure---student*/ char name[10]; int math; struct date birthday; }s1={“David Li",80, {2,10}}; printf("student name:%s\n",s1.name); printf("birthday:%d month, %d day\n",s1.birthday.month,s1.birthday.day); printf("math grade:%d\n",s1.math); return 0; }
自我參考結構 自我參考結構(self-referential structure) 在結構定義中不能有自己結構的變數. 可以有指向自己結構型態的指標變數. 這種含有指向自己結構型態指標的結構,稱之.
自我參考結構宣告—範例 自我參考結構: struct PERSON { char name[15]; /*1.定義結構的成員(欄位)*/ int age; struct PERSON * father; /*指向自己的指標*/ }; struct 結構名稱 變數1,變數2,…,變數m;/*2. 結構變數的宣告*/(同上述的結構變數宣告用法) Name[0] Name[1] ……. Name[14] age
Example7 3 2 1 0 Mike 12 Tom 35 John 65 Billy 80 null #include <stdio.h>/* 引入檔頭檔 */ #include <stdlib.h> struct PERSON { char name[15]; /* 名字 */ int age; /* 年齡 */ struct PERSON * father; /* 父親指標 */ }; int main(void) { int i; struct PERSON family[4]={{"Billy",80,NULL}, /* 結構變數的宣告 */ {"John",65}, /*設定初值*/ {"Tom",35}, /*設定初值*/ {"Mike",12}} ; /*設定初值*/ family[1].father = &family[0]; /*設定家人的關係*/ family[2].father = &family[1]; family[3].father = &family[2]; for(i=0;i<4;++i){ printf( "family[%d]=%s\t,age=%d\t ",i,family[i].name,family[i].age); if( family[i].father != NULL ) /* 判斷有無父親 */ printf(",father is %s\n",family[i].father->name ); else printf(",father unknown\n"); } system("pause"); return 0; /* <-程式正常結束,傳回0 */ Mike 12 Tom 35 John 65 Billy 80 null 3 2 1 0
練習 請設計一個三個節點(node)的環狀串列,結構名稱為ano 第一個節點資料為15,第二個節點資料為20,第三個節點資料為25 第一個節點連結第二個節點,第二個節點連接第三個節點,第三個節點連到第一個節點 自訂各節點結構指標變數,最後程式畫面印出三個節點的資料(請利用指標觀念印出)。