第9章 用戶本身創建數據類型

9.1 定義和使用結構體變量

9.1.1 本身創建結構體類型

C語言容許用戶本身創建由不一樣類型數據組成的組合型的數據結構,它稱爲結構體(structre)。編程

下面爲一個結構體類型:數組

struct Student數據結構

{      int num;                     //學號爲整型函數

       char name[20];  //姓名爲字符串oop

       char sex;                    //性別爲字符型spa

int age;    //年齡爲整型3d

       float score;                //成績爲實型指針

       char addr[30];           //地址爲字符串對象

};                                        //注意最後有一個分號blog

聲明一個結構體類型的通常形式爲:

struct 結構體名

{成員表列};

成員類型聲明形式爲:

類型名 成員名;

注意:

①結構體類型的名字是由一個關鍵字struct結構體名組合而成的。

②花括號內是該結構體所包括的子項,稱爲結構體的成員(member)

③結構體名是由用戶指定的,又稱爲「結構體標記(structure tag)」,如,上面的結構體聲明中Student就是結構體名(結構體標記)。

④花括號內是該結構體所包括的子項,稱爲結構體的成員(member)。如,上面的num,name,sex等都是成員。

⑤結構體裏面還能夠包含結構體。以下所示

struct Student   //聲明一個結構體類型 struct Student

{ int num;

char name[20];

char sex;

int age;

struct Date birthday;  //成員birthday屬於struct Date類型

char addr[30];

};

struct Date                       //聲明一個結構體類型 struct Date

{ int month;   //月

int day;    //日

int year;    //年

};

 

9.1.2 定義結構體類型變量

1. 先聲明結構體類型,再定義該類型的變量

strict Student

{      int num;                            //學號爲整型

       char name[20];         //姓名爲字符串

       char sex;                    //性別爲字符型

int age;    //年齡爲整型

       float score;                //成績爲實型

       char addr[30];           //地址爲字符串

};                                        //注意最後有一個分號

struct Student  student1, student2;

|           |          |

結構體類型名      結構體變量名

 

2. 在聲明類型的同時定義變量

struct Student

{ int num;

char name[20];

char sex;

int age;

float score;

char addr[30];

}student1, student2;

 

3. 不指定類型名而直接定義結構體類型變量

struct

{ 成員表列

}變量名錶列;

注意:

① 結構體類型與結構體變量是不一樣的概念,不要混淆。只能對變量賦值、存取或運算,而不能對一個類型賦值、存取或運算。在編譯時,對類型是不分配空間的,只對變量分配空間。

② 結構體類型中的成員名能夠與程序中的變量名相同,但兩者不表明同一對象。

③對結構體變量中的成員(即「域」),能夠單獨使用,它的做用與地位至關於普通變量。

9.1.3 結構體變量的初始化和引用

[例] 把學生的信息(學號、姓名、性別、住址)放在一個結構體變量中,而後輸出這個學生的信息。

#include <stdio.h>

int main()

{ struct Student       //聲明結構體類型struct Student

{ long int num;      //如下4行爲結構體的成員

char name[20];

char sex;

char addr[20];

}student1={10101,"Li Lin",'M',"123 Beijing Road"}; //定義結構體變量a並初始化

printf("NO.:%ld\nname:%s\nsex:%c\naddress:%s\n",student1.num,student1.name,student1.sex,student1.addr);

return 0;

}

運行結果:

 

① 在定義結構體變量時能夠對它的成員初始化。

student1={10101,"Li Lin",'M',"123 Beijing Road"}; //定義結構體變量a並初始化

注:對結構體變量初始化,不是對結構體類型初始化

②能夠引用結構體變量中成員的值,引用方式爲 結構體變量名.成員名

a.num = 100;

/*已定義了student1爲Student類型的結構體變量,則student1.num表示student1變量中的num成員,即student1的num(學號)成員*/

③若是成員自己又屬一個結構體類型,則要用若干個成員運算符,一級一級地找到最低的一級的成員

student1.num=10010; //結構體變量student1中的成員num

student1.birthday.month=6; //結構體變量student1中的成員birthday中的成員month

④結構體變量的成員能夠像普通變量同樣進行各類運算

student2.score=student1.score; //賦值運算

sum=student1.score+student2.score; //加法運算

student1.age++;   //自加運算

⑤同類的結構體變量能夠互相賦值

student1=student2;  //假設student1和student2已定義爲同類型的結構體變量

⑥能夠引用結構體變量成員的地址、引用結構體變量的地址(結構體變量的地址主要用做函數參數,傳遞結構體變量的地址)。

scanf(″%d″,&student1.num); //輸入student1.num的值

printf(″%d″,&student1); //輸出結構體變量student1的起始地址

[例] 輸入兩個學生的學號、姓名和成績,輸出成績較高的學生的學號、姓名和成績。

#include <stdio.h>

int main()

{      struct Student                  //聲明結構體類型struct Student

{ int num;

char name[20];

float score;

       }student1,student2; //定義兩個結構體變量student1,student2

scanf("%d%s%f",&student1.num,student1.name,&student1.score); //輸入學生1的數據

scanf("%d%s%f",&student2.num,student2.name,&student2.score); //輸入學生1的數據

printf("The higher score is:\n");

if(student1.score>student2.score)

printf("%d  %s  %6.2f\n",student1.num,student1.name,student1.score);

else if(student1.score<student2.score)

printf("%d  %s  %6.2f\n",student2.num,student2.name,student2.score);

else

{ printf("%d  %s  %6.2f\n",student1.num,student1.name,student1.score);

printf("%d  %s  %6.2f\n",student2.num,student2.name,student2.score);

}

return 0;

}

運行結果:

9.2 使用結構體數組

9.2.1 定義結構體數組

[例] 有3個候選人,每一個選民只能投票選一人,要求編一個統計選票的程序,前後輸入被選人的名字,最後輸出各人得票結果。

#include <string.h>

#include <stdio.h>

struct Person      //聲明結構體類型struct Person

{ char name[20];    //候選人姓名

       int count;                                        //候選人得票數

}leader[3]={"Li",0,"Zhang",0,"Sun",0}; //定義結構體數組並初始化

 

int main()

{ int i,j;

       char leader_name[20];                  //定義字符數組

for(i=1;i<=10;i++)

{ scanf("%s",leader_name); //輸入所選的候選人姓名

for(j=0;j<3;j++)

if(strcmp(leader_name,leader[j].name)==0) leader[j].count++;

}

printf("\nResult:\n");

for(i=0;i<3;i++)

printf("%5s:%d\n",leader[i].name,leader[i].count);

return 0;

}

運行結果:

 

(1)定義結構體數組通常形式是

①聲明結構體類型

struct 結構體名

{成員表列} 數組名[數組長度];

② 先聲明一個結構體類型,而後再用此類型定義結構體數組

結構體類型數組名[數組長度];

(2) 對結構體數組初始化的形式是在定義數組的後面加上:={初值表列};

struct Person leader[3]= {"Li",0,"Zhang",0,"Sun",0};

9.2.2 結構體數組的應用舉例

[例] 有n個學生的信息(包括學號、姓名、成績),要求按照成績的高低順序輸出各學生的信息。

#include <stdio.h>

struct Student     //聲明結構體類型struct Student

{ int num;

char name[20];

float score;

};

int main()

{ struct Student stu[5]={{10101,"Zhang",78},{10103,"Wang",98.5},{10106,"Li",86},

       {10108,"Ling",73.5},{10110,"Sun",100}};                 //定義結構體數組並初始化

struct Student temp;  //定義結構體變量temp,用做交換時的臨時變量

const int n=5;    //定義常變量n

int i,j,k;

printf("The order is:\n");

for(i=0;i<n-1;i++)

{ k=i;

for(j=i+1;j<n;j++)

if(stu[j].score>stu[k].score)   //進行成績的比較

k=j;

temp=stu[k]; stu[k]=stu[i]; stu[i]=temp; //stu[k]和stu[i]元素互換

}

for(i=0;i<n;i++)

printf("%6d %8s %6.2f\n",stu[i].num,stu[i].name,stu[i].score);

printf("\n");

return 0;

}

運行結果:

9.3 結構體指針

結構體指針就是指向結構體變量的指針,一個結構體變量的起始地址就是這個結構體變量的指針。

把一個結構體變量的起始地址存放在一個指針變量中,這個指針變量就指向該結構體變量。

[例] 經過指向結構體變量的指針變量輸出結構體變量中成員的信息。

#include <stdio.h>

#include <string.h>

int main()

{ struct Student   //聲明結構體類型struct Student

{ long num;

char name[20];

char sex;

float score;

};

       struct Student stu_1;       //定義struct Student類型的變量stu_1

       struct Student *p;            //定義指向struct Student 類型數據的指針變量p

       p=&stu_1;                 //p指向stu_1

       stu_1.num=10101;          //對結構體變量的成員賦值

strcpy(stu_1.name,"Li Lin"); //用字符串複製函數給stu_1.name賦值

stu_1.sex='M';

stu_1.score=89.5;

       printf("No.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",stu_1.num,stu_1.name,stu_1.sex,stu_1.score);   //輸出結果

printf("\nNo.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",(*p).num,(*p).name,(*p).sex, (*p).score);

return 0;

}

運行結果:

 

注:(*p).num也可表示爲p->num

以下代碼效果和上面的代碼效果一致

#include <stdio.h>p->

#include <string.h>

int main()

{ struct Student   //聲明結構體類型struct Student

{ long num;

char name[20];

char sex;

float score;

};

       struct Student stu_1;       //定義struct Student類型的變量stu_1

       struct Student *p;            //定義指向struct Student 類型數據的指針變量p

       p=&stu_1;                 //p指向stu_1

       stu_1.num=10101;          //對結構體變量的成員賦值

strcpy(stu_1.name,"Li Lin"); //用字符串複製函數給stu_1.name賦值

stu_1.sex='M';

stu_1.score=89.5;

       printf("No.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",stu_1.num,stu_1.name,stu_1.sex,stu_1.score);   //輸出結果

printf("\nNo.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",p->num,p->name,p->sex, p->score);

return 0;

}

若是p指向一個結構體變量stu,如下3種用法等價:

① stu.成員名

stu.num

② (*p).成員名

(*p).num

③ p->成員名

p->num

[例] 有3個學生的信息,放在結構體數組中,要求輸出所有學生的信息。

#include <stdio.h>

struct Student    //聲明結構體類型struct Student

{ int num;

char name[20];

char sex;

int age;

};

struct Student stu[3]={{10101,"Li Lin",'M',18},{10102,"Zhang Fang",'M',19},{10104,"Wang Min",'F',20}};

//定義結構體數組並初始化

int main()

{      struct Student *p;            //定義指向struct Student結構體變量的指針變量

printf(" No. Name        sex age\n");

for (p=stu;p<stu+3;p++)

printf("%5d %-20s %2c %4d\n",p->num, p->name, p->sex, p->age); //輸出結果

return 0;

}

運行結果:

 

等價效果圖:

 

9.3.3 用結構體變量和結構體變量的指針做函數參數

將一個結構體變量的值傳遞給另外一個函數,有以下方法

(1) 用結構體變量的成員做參數

例如,用stu[1].num或stu[2].name做函數實參,將實參值傳給形參。用法和用普通變量做實參是同樣的,屬於「值傳遞」方式。應當注意實參與形參的類型保持一致。

(2) 用結構體變量做實參

用結構體變量做實參時,採起的也是「值傳遞」的方式,將結構體變量所佔的內存單元的內容所有按順序傳遞給形參,形參也必須是同類型的結構體變量。在函數調用期間形參也要佔用內存單元。這種傳遞方式在空間和時間上開銷較大,若是結構體的規模很大時,開銷是很可觀的。此外,因爲採用值傳遞方式,若是在執行被調用函數期間改變了形參(也是結構體變量)的值,該值不能返回主調函數,這每每形成使用上的不便。所以通常較少用這種方法,故做了解便可。

(3) 用指向結構體變量(或數組元素)的指針做實參,將結構體變量(或數組元素)的地址傳給形參

[例] 有n個結構體變量,內含學生學號、姓名和3門課程的成績。要求輸出平均成績最高的學生的信息(包括學號、姓名、3門課程成績和平均成績)

#include <stdio.h>

#define N 3   //學生數爲3

struct Student   //創建結構體類型struct Student

{ int num;   //學號

char name[20]; //姓名

float score[3];  //3門課成績

float aver;  //平均成績

};

int main()

{ void input(struct Student stu[]); //函數聲明

struct Student max(struct Student stu[]); //函數聲明

void print(struct Student stu); //函數聲明

struct Student stu[N],*p=stu; //定義結構體數組和指針

input(p);      //調用input函數

print(max(p)); //調用print函數,以max函數的返回值做爲實參

return 0;

}

void input(struct Student stu[])  //定義input函數

{ int i;

printf("請輸入各學生的信息: 學號、姓名、三門課成績:\n");

for(i=0;i<N;i++)

{ scanf("%d %s %f %f %f",&stu[i].num,stu[i].name,

&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);  //輸入數據

stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;   //求平均成績

}

}

struct Student max(struct Student stu[]) //定義max函數

{ int i,m=0;   //用m存放成績最高的學生在數組中的序號

for(i=0;i<N;i++)

if(stu[i].aver>stu[m].aver) m=i;

//找出平均成績最高的學生在數組中的序號

return stu[m];  //返回包含該生信息的結構體元素

}

 

void print(struct Student stud)   //定義print函數

{ printf("\n成績最高的學生是:\n");

printf("學號:%d\n姓名:%s\n三門課成績:%5.1f,%5.1f,%5.1f\n平均成績: %6.2f\n",stud.num,stud.name,stud.score[0],stud.score[1],stud.score[2],stud.aver);

}

運行結果:

9.4 用指針處理鏈表

9.4.1 什麼是鏈表

鏈表是一種常見的重要的數據結構。它是動態地進行存儲分配的一種結構。

 

   鏈表有一個「頭指針」變量,圖中以head表示,它存放一個地址,該地址指向一個元素。

   鏈表中每個元素稱爲「結點」,每一個結點都應包括兩個部分:

 (1) 用戶須要用的實際數據;

 (2) 下一個結點的地址。

head指向第1個元素,第1個元素又指向第2個元素……直到最後一個元素,該元素再也不指向其餘元素,它稱爲「表尾」,它的地址部分放一個「NULL」(表示「空地址」),鏈表到此結束。

9.4.2 創建簡單的靜態鏈表

用結構體變量創建鏈表。

struct Student

{ int num;

float score;

struct Student *next;  //next是指針變量,指向結構體變量

};

成員num和score用來存放結點中的有用數據(用戶須要用到的數據)。

next是指針類型的成員,它指向struct Student類型數據(就是next所在的結構體類型)

注:上面只是定義了一個struct Student類型,並未實際分配存儲空間,只有定義了變量才分配存儲單元。

[例] 創建一個簡單鏈表,它由3個學生數據的結點組成,要求輸出各結點中的數據。

#include <stdio.h>

struct Student      //聲明結構體類型struct Student

{ int num;

float score;

struct Student*next;

};

int main()

{ struct Student a,b,c,*head,*p; //定義3個結構體變量a,b,c做爲鏈表的結點

a.num=10101; a.score=89.5;  //對結點a的num和score成員賦值

b.num=10103; b.score=90;  //對結點b的num和score成員賦值

c.num=10107; c.score=85;  //對結點c的num和score成員賦值

head=&a;     //將結點a的起始地址賦給頭指針head

a.next=&b;     //將結點b的起始地址賦給a結點的next成員

b.next=&c;     //將結點c的起始地址賦給a結點的next成員

c.next=NULL;     //c結點的next成員不存放其餘結點地址

p=head;      //使p指向a結點

do

{ printf("%ld %5.1f\n",p->num,p->score); //輸出p指向的結點的數據

p=p->next;    //使p指向下一結點

}while(p!=NULL);    //輸出完c結點後p的值爲NULL,循環終止

return 0;

}

運行結果:

 

9.4.3 創建動態鏈表

[例] 創建一個有3名學生數據的單向動態鏈表。

說明:所謂創建動態鏈表是指在程序執行過程當中從無到有地創建起一個鏈表,即一個一個地開闢結點和輸入各結點數據,並創建起先後相鏈的關係。

流程圖所示:

創建鏈表的過程示意圖:

 

程序代碼:

#include <stdio.h>

#include <stdlib.h>

#define LEN sizeof(struct Student)

struct Student

{ long num;

float score;

struct Student*next;

};

int n;  //n爲全局變量,本文件模塊中各函數都可使用它

struct Student *creat(void)

//定義函數。此函數返回一個指向鏈表頭的指針

{ struct Student *head;

struct Student *p1,*p2;

n=0;

p1=p2=(struct Student*) malloc(LEN);  //開闢一個新單元

scanf("%ld,%f",&p1->num,&p1->score);

//輸入第1個學生的學號和成績

head=NULL;

while(p1->num!=0)

{ n=n+1;

if(n==1) head=p1;

else p2->next=p1;

p2=p1;

p1=(struct Student*)malloc(LEN);

//開闢動態存儲區,把起始地址賦給p1

scanf("%ld,%f",&p1->num,&p1->score);

//輸入其餘學生的學號和成績

}

p2->next=NULL;

return(head);

}

int main()

{ struct Student *pt;

       pt=creat(); //函數返回鏈表第一個結點的地址

printf("\nnum:%ld\nscore:%5.1f\n",pt->num,pt->score);

//輸出第1個結點的成員值

return 0;

};

運行結果:

 

9.4.4 輸出鏈表

[例] 編寫一個輸出鏈表的函數print。

#include <stdio.h>

#include <stdlib.h>

#define LEN sizeof(struct Student)

struct Student     //聲明結構體類型struct Student

{ long num;

float score;

struct Student *next;

};

int n;      //全局變量n

void print(struct Student*head)  //定義print函數

{ struct Student*p;   //在函數中定義struct Student類型的變量p

printf("\nNow,These %d records are:\n",n);

p=head;     //使p指向第1個結點

if(head!=NULL)   //若不是空表

do

{ printf("%ld %5.1f\n",p->num,p->score); //輸出一個結點中的學號與成績

p=p->next;  //p指向下一個結點

}while(p!=NULL);  //當p不是"空地址"

}

流程圖:

9.5 共用體類型

9.5.1 什麼是共用體類型

使幾個不一樣類型的變量共享同一段內存的結構,稱爲 「共用體」類型的結構。

定義共用體類型變量的通常形式爲:

union共用體名

{ 成員表列

}變量表列;

定義共用體的形式:

(1) 在聲明類型同時定義變量

union Data

{ int i;

//表示不一樣類型的變量i,ch,f能夠存放到同一段存儲單元中

char ch;

       float f;

}a,b,c;    //在聲明類型同時定義變量

(2) 先聲明類型,後定義變量

union Data   //聲明共用體類型

{ int i;

char ch;

float f;

};

union Data a,b,c; //用共用體類型定義變量

(3) 定義共用體,可是沒有定義共用體類型名

union  //沒有定義共用體類型名

{ int i;

char ch;

       float f;

}a,b,c;

共用體與結構體的區別?

結構體變量所佔內存長度是各成員佔的內存長度之和,每一個成員分別佔有其本身的內存單元。

而共用體變量所佔的內存長度等於最長的成員的長度,幾個成員共用一個內存區。

9.5.2 引用共用體變量的方式

a.i   //引用共用體變量中的整型變量i

a.ch  //引用共用體變量中的字符變量ch

a.f          //引用共用體變量中的實型變量f

注意,不能引用共用體變量,而只能引用共用體變量中的成員。

printf(″%d″,a);    //這是錯誤的

printf(″%d″,a.i);  //這是正確的

9.5.3 共用體類型數據的特色

(1) 同一個內存段能夠用來存放幾種不一樣類型的成員,但在每一瞬時只能存放其中一個成員,而不是同時存放幾個

(2) 能夠對共用體變量初始化,但初始化表中只能有一個常量

(3) 共用體變量中起做用的成員是最後一次被賦值的成員,在對共用體變量中的一個成員賦值後,原有變量存儲單元中的值就被取代

(4) 共用體變量的地址和它的各成員的地址都是同一地址

(5) 不能對共用體變量名賦值,也不能企圖引用變量名來獲得

一個值。C 99容許同類型的共用體變量互相賦值

(6) C 99容許用共用體變量做爲函數參數

(7) 共用體類型能夠出如今結構體類型定義中,也能夠定義共用體數組。反之,結構體也能夠出如今共用體類型定義中,數組也能夠做爲共用體的成員

[例] 有若干我的員的數據,其中有學生和教師。學生的數據中包括: 姓名、號碼、性別、職業、班級。教師的數據包括: 姓名、號碼、性別、職業、職務。要求用同一個表格來處理。

 

//定義結構體與共用體

#include <stdio.h>

struct      //聲明無名結構體類型

{ int num;     //成員num(編號)

char name[10];   //成員name(姓名)

char sex;     //成員sex(性別)

char job;     //成員job(職業)

union     //聲明無名共用體類型

{ int clas;    //成員clas(班級)

              char position[10];            //成員position(職務)

}category;    //成員category是共用體變量

}person[2];     //定義結構體數組person,有兩個元素

//執行函數

int main()

{ int i;

for(i=0;i<2;i++)

{ printf("please enter the data of person:\n");

scanf("%d %s %c %c",&person[i].num,person[i].name,&person[i].sex,&person[i].job);  //輸入前4項

if(person[i].job=='s')

scanf("%d",&person[i].category.clas);          //如是學生,輸入班級

else if(person[i].job=='t')

scanf("%s",person[i].category.position);          //如是教師,輸入職務

else

printf("Input error!");             //如job不是's'和't',顯示「輸入錯誤」

}

printf("\n");

printf("No.namesex job class/position\n");

for(i=0;i<2;i++)

{ if (person[i].job=='s')              //如果學生

printf("%-6d%-10s%-4c%-4c%-10d\n",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.clas);

else                  //如果教師

printf("%-6d%-10s%-4c%-4c%-10s\n",person[i].num, person[i].name,person[i].sex,person[i].job,person[i].category.position);

}

return 0;

}

運行結果:

9.6 使用枚舉類型

聲明枚舉類型的通常形式:

enum [枚舉名]{枚舉元素列表}

例:enum Weekday{sun,mon,tue,wed,thu,fri,sat};

若是一個變量只有幾種可能的值,則能夠定義爲枚舉(enumeration)類型,所謂「枚舉」就是指把可能的值一一列舉出來,變量的值只限於列舉出來的值的範圍內。

聲明枚舉類型用enum開頭。花括號中的sun,mon,…,sat稱爲枚舉元素或 枚舉常量。

也能夠不聲明有名字的枚舉類型,而直接定義枚舉變量:

enum {sun,mon,tue,wed,thu,fri,sat}workday,weekend;

 

(1) C編譯對枚舉類型的枚舉元素按常量處理,故稱枚舉常量。不要由於它們是標識符(有名字)而把它們看做變量,不能對它們賦值

(2) 每個枚舉元素都表明一個整數,C語言編譯按定義時的順序默認它們的值爲0,1,2,3,4,5…。也能夠在定義枚舉類型時顯式地指定枚舉元素的數值

(3) 枚舉元素能夠用來做判斷比較。枚舉元素的比較規則是按其在初始化時指定的整數來進行比較的

[例] 口袋中有紅、黃、藍、白、黑5種顏色的球若干個。每次從口袋中前後取出3個球,問獲得3種不一樣顏色的球的可能取法,輸出每種排列的狀況。

#include <stdio.h>

int main()

{ enum Color {red,yellow,blue,white,black};     //聲明枚舉類型enum Color

enum Color i,j,k,pri;        //定義枚舉變量i,j,k,pri

int n,loop;

n=0;

for(i=red;i<=black;i++)        //外循環使i的值從red變到black

for(j=red;j<=black;j++)       //中循環使j的值從red變到black

if(i!=j) //若是二球不一樣色

{ for (k=red;k<=black;k++)    //內循環使k的值從red變到black

if ((k!=i) && (k!=j))    //若是3球不一樣色

{ n=n+1;     //符合條件的次數加1

printf("%-4d",n);    //輸出當前是第幾個符合條件的組合

for(loop=1;loop<=3;loop++)  //前後對3個球分別處理

{ switch (loop)   //loop的值從1變到3

{ case 1: pri=i;break; //loop的值爲1時,把第1球的顏色賦給pri

                                                        case 2: pri=j;break;   //loop的值爲2時,把第2球的顏色賦給pri

case 3: pri=k;break; //loop的值爲3時,把第3球的顏色賦給pri

default:break;

}

switch (pri)//根據球的顏色輸出相應的文字

{ case red:printf("%-10s","red");break;  //pri的值等於枚舉常量red時輸出"red"

case yellow: printf("%-10s","yellow");break; //pri的值等於枚舉常量yellow時輸出"yellow"

                                                        case blue: printf("%-10s","blue");break;   //pri的值等於枚舉常量blue時輸出"blue"

case white: printf("%-10s","white");break; //pri的值等於枚舉常量white時輸出"white"

case black: printf("%-10s","black"); break; //pri的值等於枚舉常量black時輸出"black"

default:break;

}

}

printf("\n");

}

}

printf("\ntotal:%5d\n",n);

return 0;

}

 

 

9.7 用typedef聲明新類型名

1. 簡單地用一個新的類型名代替原有的類型名

typedef int Integer; //指定用Integer爲類型名,做用與int相同

typedef float Real; //指定用Real爲類型名,做用與float相同

2. 命名一個簡單的類型名代替複雜的類型表示方法

① 命名一個新的類型名錶明結構體類型

② 命名一個新的類型名錶明數組類型

③ 命名一個新的類型名錶明指針類型

④命名一個新的類型名錶明指向函數的指針類型

typedef struct

{ int month;

int day;

       int year;

}Date;    //聲明瞭一個新類型名Date,表明結構體類型

Date birthday;                 //定義結構體類型變量birthday,不要寫成struct Date birthday;

Date*p;    //定義結構體指針變量p,指向此結構體類型數據

 

typedef int Num[100]; //聲明Num爲整型數組類型名

Num a;    //定義a爲整型數組名,它有100個元素

 

typedef char*String; //聲明String爲字符指針類型

String p,s[10];   //定義p爲字符指針變量,s爲字符指針數組

 

ypedef int (*Pointer)(); //聲明Pointer爲指向函數的指針類型,該函數返回整型值

Pointer p1,p2;   //p1,p2爲Pointer類型的指針變量

聲明一個新的類型名的方法是:

① 先按定義變量的方法寫出定義體(如: int i;)

② 將變量名換成新類型名(例如: 將i換成Count)

③ 在最前面加typedef(例如: typedef int Count)

④ 而後能夠用新類型名去定義變量

簡單地說,就是按定義變量的方式把變量名換上新類型名,並在最前面加typedef,就聲明瞭新類型名錶明原來的類型。

以定義上述的數組類型爲例來講明:

① 先按定義數組變量形式書寫: int a[100]

② 將變量名a換成本身命名的類型名: int Num[100]

③ 在前面加上typedef,獲得typedef int Num[100]

④ 用來定義變量: Num a; 至關於定義了: int a[100];

一樣,對字符指針類型,也是:

① char *p;  //定義變量p的方式

② char *String; //用新類型名String取代變量名p

③ typedef char *String; //加typedef

④ String p; //用新類型名String定義變量,至關char *p;

習慣上,常把用typedef聲明的類型名的第1個字母用大寫表示,以便與系統提供的標準類型標識符相區別。

對"typedef聲明新類型名"說明

(1) typedef的方法其實是爲特定的類型指定了一個同義字(synonyms)

(2) 用typedef只是對已經存在的類型指定一個新的類型名,而沒有創造新的類型

(3) 用tyoedef聲明數組類型、指針類型,結構體類型、共用體類型、枚舉類型等,使得編程更加方便

(4) typedef與#define表面實質不一樣的。#define是在預編譯時處理的,它只能做簡單的字符串替換,而typedef是在編譯階段處理的,且並不是簡單的字符串替換

(5) 當不一樣源文件中用到同一類型數據(尤爲是像數組、指針、結構體、共用體等類型數據)時,經常使用typedef聲明一些數據類型。能夠把全部的typedef名稱聲明單獨放在一個頭文件中,而後在須要用到它們的文件中用#include指令把它們包含到文件中。這樣編程者就不須要在各文件中本身定義typedef名稱了

(6) 使用typedef名稱有利於程序的通用與移植;有時程序會依賴於硬件特性,用typedef類型就便於移植

相關文章
相關標籤/搜索