




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
數組為相同類型的變量描述與使用帶來了方便,如果數組元素是一個結構體變量,那么此數組被稱為結構體變量,本節將介紹結構體變量及其應用。在使用過程中,對于相同類型的變量可以用數組進行描述,例如描述多個學生信息的變量,可以用數組進行描述。如果學生數組的每個元素是一個結構體變量,則該數組就可以表示多個學生的信息。這樣的數組叫結構體數組。7.3結構體數組7.3.1結構體數組的定義與初始化1、結構體數組的定義結構體數組的定義只是結構體變量定義的特殊情況,因此定義的方法與結構體變量定義相同,有如下三種定義方法。(1)第一種形式,先定義結構體類型,然后再定義結構體類型的數組。例如:structstu_record //定義一個結構體類型
{intnum;charname[10];……};structstu_recordstu[10]; //定義一個結構體數組,含10個
structstudent類型的元素(2)第二種定義方法,在定義類型的同時定義一個結構體類型的數組。例如:structstu_record{intnum;charname[20];……}stu[10]; //定義類型的同時定義一個數組(3)第三種形式,直接定義一個結構體類型的數組。例如:struct{intnum;charname[20];……}stu[10]; //直接定義一個結構體類型的數組2、結構體數組的初始化結構體類型數組的初始化遵循基本數據類型數組的初始化規律,在定義數組的同時,對其中的每一個元素進行初始化。例如:structstud{ intnum;charname[10];intage;floatscore;}stu[2]={{10,“Zhangsan”,19,98.5},{13,“Ligao”,18,96.5,}};如果在定義數組的同時進行初始化,可以省略數組的長度,系統會根據初始化數據的多少來確定數組的長度。例如:structtask_finished{chartask[20];chartag;}task_F_or_T[]={{“exer1”,“F”},{“exer2”,“T”},{“exer3”,“F”}};結構體數組task_F_or_T的長度,系統自動確認為3。注意:初始化是在定義的時候完成的,非定義時只有重新賦值,不能初始化!例如:structstudent{intnum;intage;floatscore};structstudentboy[2];boy[0]={102,19,96.5};boy[1]={103,18,95.5};……這時程序編譯時會出錯,原因是:結構體數組boy[2]的定義在語句structstudentboy[2]時已完成,因此boy[0]={102,19,96.5}和語句boy[1]={103,18,95.5}就不能看成是初始化,它是重新賦值,C語法是禁止結構體這樣賦值的!這時程序編譯時會出錯,原因是:結構體數組boy[2]的定義在語句structstudentboy[2]時已完成,因此boy[0]={102,19,96.5}和語句boy[1]={103,18,95.5}就不能看成是初始化,它是重新賦值,C語法是禁止結構體這樣賦值的!7.3.2結構體變量的使用(1)結構體變量的成員使用方式
結構體變量名.成員名
如:stu[i].nmu、stu[i].name、stu[i].agestu1.nmu、、stu1.agestu2.nmu、、stu2.age結構體變量的成員按照它的簡單變量類型的使用方法直接使用。【例7-5】用鍵盤輸入的方法給學生結構體變量賦值,并打印學生信息.typedefstructstudent//定義結構體類型
{charnum[10];charname[20];intage;}stud;voidmain(){inti=0;studstu[2];//定義結構體變量數組printf("學號
姓名
年齡\n");for(i=0;i<2;i++)scanf("%s%s%d",stu[i].num,stu[i].name,&stu[i].age);}for(i=0;i<2;i++)printf("學號:%s姓名:%s年齡:%d\n",stu[i].num,stu[i].name,stu[i].age);return0;}按如下數據輸入:20140101張三1920140102李四20輸出結果:學號:20140101姓名:張三
年齡:19學號:20140102姓名:李四
年齡:20
從以上例子,可以知道,結構體變量是一種數據組織形式,當我們通過成員操作符號“.”取出要使用的成員后,其使用方法與該成員的簡單變量類型的使用方法完全一致.
如stu[i].num是字符串類型,我們按字符串的使用方法使用該成員,而stu[i].age是整形數,所以完全按照整形數變量來使用該成員。當結構體內部的成員是一個結構體的情況:【例7-6】引用結構體內結構體的成員變量示例。typedefstructdate//定義日期結構體{intyear;intmonth;intday;}date;typedefstructstudent//定義stud結構體類型{charnum[10];charname[20];intage;datebirthday;}stud;intmain(){inti=0;studstu;//定義結構體變量printf("學號
姓名
年齡年月日\n");scanf("%s%s%d%d%d%d",stu.num,,&stu.age,&stu.birthday.year,&stu.birthday.month,&stu.birthday.day);printf("學號:%s姓名:%s年齡:%d出生日期%d-%d-%d\n",stu.num,,stu.age,stu.birthday.year,stu.birthday.month,stu.birthday.day);return0;} 例題中對于出身年月日的引用分別是:stu.birthday.year,stu.birthday.month,stu.birthday.day由于birthday是stu的一個成員所以我們引用birthday的方法是stu.birthday,由于birthday還是一個結構體變量所以我們對于它的三個成員繼續用“.”引用,分別是:出生年份stu.birthday.year;出生月份stu.birthday.month;出生日
stu.birthday.day;【例7-7】結構體變量賦值操作#include"string"typedefstructdate//定義日期結構體{intyear;intmonth;intday;}date;typedefstructstudent//定義stud結構體類型{charnum[10];charname[20];intage;datebirthday;}stud;intmain(){inti=0;studstu,stu1,stu2;//定義結構體變量printf("學號
姓名
年齡年月日\n");scanf("%s%s%d%d%d%d",stu.num,,&stu.age,&stu.birthday.year,&stu.birthday.month,&stu.birthday.day);stu1=stu;//直接拷貝結構體變量strcpy(stu2.num,stu1.num);//逐項拷貝結構體變量strcpy(,);stu2.age=stu1.age;stu2.birthday.year=stu1.birthday.year;stu2.birthday.month=stu1.birthday.month;stu2.birthday.day=stu1.birthday.day;printf("stu:學號:%s姓名:%s年齡:%d出生日期%d-%d-%d\n",stu.num,,stu.age,stu.birthday.year,
stu.birthday.month,
stu.birthday.day); printf("stu1:學號:%s姓名:%s年齡:%d出生日期%d-%d-%d\n",stu1.num,,stu1.age,stu1.birthday.year,stu1.birthday.month,stu1.birthday.day); printf("stu2:學號:%s姓名:%s年齡:%d出生日期%d-%d-%d\n",stu2.num,,stu2.age,stu2.birthday.year,stu2.birthday.month,stu2.birthday.day); return0;}從鍵盤輸入:20140101張三21198256運行結構:stu:學號:20140101姓名:張三
年齡:21出生日期1982-5-6stu1:學號:20140101姓名:張三
年齡:21出生日期1982-5-6stu2:學號:20140101姓名:張三
年齡:21出生日期1982-5-6結構體變量有兩種拷貝方法,第一種是直接使用“=”對結構體變量拷貝,如上例中stu1=stu;直接將stu的內容拷貝給stu1;第二種采用逐項賦值的方式拷貝結構體變量,如:strcpy(stu2.num,stu1.num);//逐項拷貝結構體變量strcpy(,);stu2.age=stu1.age;stu2.birthday.year=stu1.birthday.year;stu2.birthday.month=stu1.birthday.month;stu2.birthday.day=stu1.birthday.day;這兩種拷貝方法完全等效。【例7-8】建立同學通訊錄。#include"stdio.h"#defineN3structyearbook{charname[20];charphone[10];};main(){structyearbookcla[N];
inti;for(i=0;i<N;i++)
{printf("inputname:\n");gets(cla[i].name);printf("inputphone:\n");gets(cla[i].phone);}printf("name\t\t\tphone\n\n");for(i=0;i<NUM;i++)printf("%s\t\t\t%s\n",cla[i].name,cla[i].phone);}本程序中定義了一個結構體yearbook,它有兩個成員name和phone用來表示姓名和電話號碼。在主函數中定義cla為具有yeaebook類型的結構數組。在for語句中,用gets函數分別輸入各個元素中兩個成員的值。然后又在for語句中用printf語句輸出各元素中兩個成員值。7.4結構體與函數7.4.1結構體變量作函數的參數結構體變量作為函數的形式參數時和簡單變量作為形式參數一樣,函數在調用時會為結構體變量在棧中分配該結構體變量相同大小的空間,并將結構體變量實際參數的內容拷貝到該空間里。函數結束后該空間被釋放。函數中對結構體變量做的任何修改將,函數退出后不再有效。【例7-9】結構體變量作為函數的形式參數。typedefstructdate//定義日期結構體{intyear;intmonth;intday;}date;typedefstructstudent//定義stud結構體類型{charnum[10];charname[20];intage;datebirthday;}stud;voidprintfstruct(studstu)//結構體變量作為函數參數{stu.birthday.year=0;stu.birthday.month=0;stu.birthday.day=0; printf("學號:%s姓名:%s年齡:%d出生日期%d-%d-%d\n",stu.num,,stu.age,stu.birthday.year,stu.birthday.month,stu.birthday.day); //函數內部打印結構體形式參數內容}intmain(){inti=0;studstu;//定義結構體變量printf("學號
姓名
年齡年月日\n");scanf("%s%s%d%d%d%d",stu.num,,&stu.age,&stu.birthday.year,&stu.birthday.month, &stu.birthday.day);printfstruct(stu);printf("學號:%s姓名:%s年齡:%d出生日期%d-%d-%d\n",stu.num,,stu.age,stu.birthday.year,stu.birthday.month,stu.birthday.day); //調用函數后再次打印結構體內容return0;}從鍵盤輸入:20140101張三21198256運行結果:學號:20140101姓名:張三
年齡:21出生日期0-0-0學號:20140101姓名:張三
年齡:21出生日期1982-5-6由于形式參數stu被定義為結構體,在函數內部依然使用“.”引用形式參數的各成員。和簡單變量一樣在函數內部使用的是實際參數的副本,如果函數中對結構體內部成員的值做了改變,當函數結束時,這些改變將不會在實際參數上生效。輸出結構第一次打印時是在函數內部,將出生年月日都改為了0,顯示的結果是出生年月日都為0,當函數退出再次打印出生年月日時,還是保持原來的值。當我們想通過函數改變結構體變量的值時,必須采用指針作為函數的參數才能真正改變結構體變量的值。由于在函數內部是使用指針操作結構體變量,直接操作的是結構體實際存儲的空間,所以這樣的修改是生效的。7.4.2返回值為結構體變量的函數在一個函數的內部,函數的返回值通過return語句實現。return返回的通常是一個拷貝,不管是變量、對象還是指針都是返回拷貝。返回值分為以下幾種情況:1)返回一個基本類型的變量;2)返回非動態分配的指針;3)返回動態分配的指針;4)返回非基本類型(對象等)。本節將以例子的形式介紹返回值為結構體的函數。【例7-10】函數的返回值為結構體變量。#include<stdio.h>structdate{intyear,month,day;};structdateinput(){structdatet;scanf("%d%d%d",&t.year,&t.month,&t.day);returnt;}voiddisp(structdated){printf("%d/%d/%d\n",d.year,d.month,d.day);}intmain(){structdated1;d1=input();disp(d1);}程序運行時從鍵盤輸入:201111程序運行后的輸出結果是:2011/1/1通過以上例子可以看出,函數返回變量類型為結構體類型時對解決復雜問題帶來方便,可以通過簡潔的描述應對復雜的數據要求。7.5結構體與指針7.5.1結構體指針的定義與使用如果指針變量中存放某個結構體變量的首地址時,則此指針變量被稱為結構指針變量。此時可以通過結構指針訪問該結構變量,這與數組指針和函數指針的情況是相同的。結構指針變量通常需要先說明后使用,其說明的一般形式為:struct結構名*結構指針變量名例如,在前面的例題中定義date這個結構,如要說明一個指向date的指針變量pdat,可寫為:structdate*pdat;當然也可在定義date結構時同時說明pdat。與前面討論的各類指針變量相同,結構指針變量也必須要先賦值后才能使用。
賦值是把結構變量的首地址賦予該指針變量,不能把結構名賦予該指針變量。如果birthday是被說明為date類型的結構變量,則:pdat=&birthday是正確的,而:pdat=&date是錯誤的。結構名和結構變量是兩個不同的概念,不能混淆。結構名只能表示一個結構形式,編譯系統并不對它分配內存空間。只有當某變量被說明為這種類型的結構時,才對該變量分配存儲空間。因此上面&date這種寫法是錯誤的,不可能去取一個結構體類型名的首地址。有了結構指針變量,就能更方便地訪問結構體變量的各個成員。其訪問的一般形式為:(*結構體指針變量).成員名或為:
結構體指針變量->成員名例如:(*pdat).year或者:pdat->year應該注意(*pdat)兩側的括號不可少,因為成員符“.”的優先級高于“*”。如去掉括號寫作*pdat.year則等效于*(pdat.year),這樣,意義就完全不對了。
下面的例題將為我們說明如何使用指向結構體的指針變量引用結構體。【例7-13】通過指針引用結構體變量。typedefstructstudent//定義結構體類型
{charnum[10];charname[20];intage;}stud;intmain(intargc,char*argv[]){inti=0;stud*pstu=NULL;//定義結構體指針變量studstu;//定義結構體變量pstu=&stu;//結構體指針變量指向結構體變量printf("學號
姓名
年齡\n");scanf("%s%s%d",pstu->num,pstu->name,&pstu->age);printf("學號:%s姓名:%s年齡:%d\n",pstu->num,pstu->name,pstu->age);return0;}從鍵盤輸入:20140101張三19運行結果:學號:20140101姓名:張三
年齡:19此例題說明,和簡單變量指針變量一樣,結構體指針變量使用前需要給結構體指針變量賦值,該值等于結構體變量的地址。如:
pstu=&stu;//結構體指針變量指向結構體變量將stu結構體變量的地址&stu地址賦值給pstu;當使用結構體指針引用結構體變量成員時不再使用“.”成員符號,而是使用“->”引用成員變量,如:pstu->num、pstu->name、pstu->age。7.5.2結構體指針與結構體數組指針變量可以指向一個結構體數組,這時結構體指針變量的值是整個結構體數組的首地址。結構體指針變量也可指向結構體數組的一個元素,這時結構體指針變量的值是該結構體數組元素的首地址。設ps為指向結構體數組的指針變量,則ps也指向該結構體數組的0號元素,ps+1指向1號元素,ps+i則指向i號元素。這與普通數組的情況是一致的。【例7-14】用指針變量輸出結構體數組。struct
stu{
int
num;char*name;charsex;floatscore;}boy[5]={{101,"Zhouping",'M',45},{102,"Zhangping",'M',62.5},{103,"Lioufang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58}};main(){
struct
stu*ps;
printf("No\tName\t\t\tSex\tScore\t\n");for(ps=boy;ps<boy+5;ps++)printf("%d\t%s\t\t%c\t%f\t\n",ps->num,ps->name,ps->sex,ps->score);}在程序中,定義了stu結構體類型的外部數組boy并作了初始化賦值。在main函數內定義ps為指向stu類型的指針。在循環語句for的表達式1中,ps被賦予boy的首地址,然后循環5次,輸出boy數組中各成員值。應該注意的是,一個結構體指針變量雖然可以用來訪問結構體變量或結構體數組元素的成員,但是,不能使它指向一個成員。也就是說不允許取一個成員的地址來賦予它。因此,下面的賦值是錯誤的。ps=&boy[1].sex;而只能是:ps=boy;(賦予數組首地址)或者是:ps=&boy[0];(賦予0號元素首地址)在ANSIC標準中允許用結構體變量作函數參數進行整體傳送。但是這種傳送要將全部成員逐個傳送,特別是成員為數組時將會使傳送的時間和空間開銷很大,嚴重地降低了程序的效率。因此最好的辦法就是使用指針,即用指針變量作函數參數進行傳送。這時由實參傳向形參的只是地址,從而減少了時間和空間的開銷。【例7-15】計算一組學生的平均成績和不及格人數。用結構體指針變量作函數參數編程。structstu{intnum;char*name;charsex;floatscore;}boy[5]={{101,"Liping",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58},};main(){structstu*ps;voidave(structstu*ps);ps=boy;ave(ps);}voidave(structstu*ps){intc=0,i;floatave,s=0;for(i=0;i<5;i++,ps++)
{s+=ps->score;if(ps->score<60)c+=1;}printf("s=%f\n",s);ave=s/5;printf("average=%f\ncount=%d\n",ave,c);}本程序中定義了函數ave,其形參為結構體指針變量ps。boy被定義為外部結構體數組,因此在整個源程序中有效。在main函數中定義說明了結構體指針變量ps,并把boy的首地址賦予它,使ps指向boy數組。然后以ps作實參調用函數ave。在函數ave中完成計算平均成績和統計不及格人數的工作并輸出結果。由于本程序全部采用指針變量作運算和處理,故速度更快,程序效率更高。C語言中使用數組時,數組的長度由定義說明,整個程序中固定不變。C語言中不允許動態數組類型。但在實際應用中,所需的內存空間取決于實際輸入的數據,而無法預先確定。顯然用數組的辦法很難解決。為了解決上述問題,C語言提供了一些內存管理函數,這些內存管理函數可以按需要動態地分配內存空間,也可把不再使用的空間回收待用。此時引入鏈表,本節將介紹鏈表的定義及其應用。7.6鏈表7.6.1鏈表的定義相同類型的結點占有同樣大小的內存空間,在使用過程中,為了解決結點數目動態變化問題,鏈表是一種有效的解決方法。例如使用動態存儲的方法解決學生數目變化的情況。有一個學生就分配一個結點,無須預先確定學生的準確人數,某學生退學,可刪去該結點,并釋放該結點占用的存儲空間。從而節約了寶貴的內存資源。另一方面,用數組的方法必須占用一塊連續的內存區域。而使用動態分配時,每個結點之間可以是不連續的(結點內是連續的)。結點之間的聯系可以用指針實現。即在結點結構中定義一個成員項用來存放下一結點的首地址,這個用于存放地址的成員,常把它稱為指針域。可在第一個結點的指針域內存入第二個結點的首地址,在第二個結點的指針域內又存放第三個結點的首地址,如此串連下去直到最后一個結點。最后一個結點因無后續結點連接,其指針域可賦為0。這樣一種連接方式,在數據結構中稱為“鏈表”。鏈表的簡單示意如圖7-1:圖7-1鏈表示意圖圖7-1中,第0個結點稱為頭結點,它存放有第一個結點的首地址,它沒有數據,只是一個指針變量。以下的每個結點都分為兩個域,一個是數據域,存放各種實際的數據,如學號num,姓名name,性別sex和成績score等。另一個域為指針域,存放下一結點的首地址。鏈表中的每一個結點都是同一種結構類型。例如,一個存放學生學號和成績的結點應為以下結構:structstu{intnum;intscore;structstu*next;}前兩個成員項組成數據域,后一個成員項next構成指針域,它是一個指向stu類型結構的指針變量。7.6.2鏈表的常用操作鏈表的基本操作對鏈表的主要操作有以下幾種:建立鏈表;結構的查找與輸出;插入一個結點;刪除一個結點;下面通過例題來說明這些操作。【例7-16】建立一個三個結點的鏈表,存放學生數據。為簡單起見,我們假定學生數據結構中只有學號和年齡兩項。可編寫一個建立鏈表的函數creat。#defineNULL0#defineTYPEstructstu#defineLENsizeof(structstu)structstu{intnum;intage;structstu*next;};TYPE*creat(intn){structstu*head,*pf,*pb;inti;for(i=0;i<n;i++){pb=(TYPE*)malloc(LEN);printf("inputNumberandAge\n");
scanf("%d%d",&pb->num,&pb->age);
if(i==0)pf=head=pb;elsepf->next=pb;pb->next=NULL;pf=pb;}return(head);}在函數外首先用宏定義對三個符號常量作了定義。這里用TYPE表示struct
stu,用LEN表示sizeof(struct
stu)主要的目的是為了在以下程序內減少書寫并使閱讀更加方便。結構stu定義為外部類型,程序中的各個函數均可使用該定義。creat函數用于建立一個有n個結點的鏈表,它是一個指針函數,它返回的指針指向stu結構。在creat函數內定義了三個stu結構的指針變量。head為頭指針,pf為指向兩相鄰結點的前一結點的指針變量。pb為后一結點的指針變量。【例7-17】鏈表的建立與內容輸出。#include<stdio.h>structdate{intyear,month,day;structdate*next;};intmain(){structdated1={2010,10,10,0};structdated2={2010,12,31,0};structdated3={2011,1,1,0};structdate*p=&d1;d1.next=&d2;d2.next=&d3;d3.next=NULL;while(p!=NULL){printf("%d/%d/%d\n",p->year,p->month,p->day);p=p->next;}}程序的運行結果是:2010/10/102010/12/312011/1/1結構體數據類型由用戶定義的多個成員組成,各個成員占用不同的內存空間。本節將介紹共用體構造數據類型。7.7共用體7.7.1共用體類型的定義結構體由不同的數據成員組成,并且各成員各自占有內存空間。共用體也是一種由用戶自定義的數據類型,也可以由若干種數據類型組合而成,組成共用體數據的若干個數據也稱為成員。和結構體不同的是,共用體是把幾種不同類型的變量放在同一段內存單元中,且各個變量都是從同一地址開始存放。即使用覆蓋技術,幾個變量相互覆蓋,從而達到使幾個不同的變量共同占用同一段內存的目的。假定在一個C語言程序中定義了一個共用體變量S,S中含有三個不同類型的成員,第一成員為字符型變量ch需要一個存儲單元,第二個成員為整型變量i需要2個存儲單元,第三個成員為單精度型變量f需要四個存儲單元。實際上定義共用體變量S時,系統只給變量S分配4個存儲單元,3個成員間的對應關系為:共用體變量定義時占用的存儲單元是其成員所占用的最大存儲單元數,各成員不能同時使用存儲單元,每次均只能一個成員使用共用體存儲單元。圖7-2共用體變量S占用的存儲單元數為4。定義共用體類型的方法與定義結構體類型的方法類似:union共用體名{數據類型1成員名1;數據類型2成員名2;……數據類型n成員名n;}共用體變量列表;其中:共用體名是用戶命名的標識符。數據類型通常是基本數據類型,也可以是結構體類型、共用體類型等其它類型。成員名是用戶取的標識符,用來標識所包含的成員名稱。例如:unionexample{chara[100];//該成員占用100個存儲單元intb[100];//該成員占用400個存儲單元floatc[100];//該成員占用400個存儲單元}array;//共用體變量array占用400個存儲單元注意:共用體變量中每個成員所占的存儲單元是連續的,而且都是從分配的連續存儲單元的第一個存儲單元開始存放數據,所以對共用體變量來說所有成員的首地址是相同的。7.7.2共用體變量的定義與引用1、共用體變量的定義定義了某個共用體后,就可以使用它來定義相應共用體類型的變量、數組等。方法如下:(1)先定義共用體,然后定義變量、數組。(2)同時定義共用體和變量、數組。(3)定義無名稱的共用體的同時定義變量、數組。(1)unionexam{int
i;charch;};unionexama,m[3];(2)unionexam{int
i;charch;}a,m[3];(3)union{
int
i;charch;}a,m[3];由于共用體變量中的成員不能同時起作用,因此對共用體變量、數組的定義不能賦初值,只能在程序中對其成員進行賦值。2、共用體變量的引用與結構體變量的引用方式類似:先定義,后使用;只能引用具體成員,而不能直接引用變量。例如,前面已定義了共用體變量a,下面的引用方式是正確的:a.i(引用共用體變量中的整型變量i)a.ch(引用共用體變量中的字符型變量ch)不能只引用共用體變量,如:printf(“%d”,a);是錯誤的。這是因為a的存儲區有2種類型,分別占不同長度的存儲空間,僅寫變量名a,難以讓系統確定究竟是要輸出哪一個成員。應該寫成printf(“%d”,a.i)或printf(“%c”,a.ch)。【例7-18】寫出下列程序的輸出結果。main(){unionzj{inta;charch[2];}au;au.a=298;printf("%d,%d\n",au.ch[0],au.ch[1]);}運行結果為:42,17.8枚舉類型實際應用中,有些變量的取值被限制在特定的范圍內。例如,一年只有特定的十二個月,一個星期只有特定的七天等等。對于此類變量,C語言提供了一種稱為“枚舉”的類型。在“枚舉”類型的定義中列舉出所有可能的取值,被說明為該“枚舉”類型的變量取值不能超過定義的范圍。但要說明的是,枚舉類型是一種基本數據類型,而不是一種構造類型,因為它不能再分解為任何基本類型。1、枚舉類型的定義與枚舉變量說明1)枚舉類型定義的一般形式為:enum枚舉名{枚舉值表};在枚舉值表中應羅列出所有可用值。這些值也稱為枚舉元素。例如:enumweekday{monday,,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};該枚舉名為weekday,枚舉值共有7個,即一周中的七天。凡被說明為weekday類型變量的取值只能是七天中的某一天。(2)枚舉變量的說明如同結構體和聯合體一樣,枚舉變量也可用不同的方式說明,即先定義后說明,同時定義說明或直接說明。設有變量a,b,c被說明為上述的weekday,可采用下述任一種方式:變量說明方式一:enumweekday{sun,mou,tue,wed,thu,fri,sat};enumweekdaya,b,c;變量說明方式二:enumweekday{sun,mou,tue,wed,thu,fri,sat}a,b,c;變量說明方式三:enum{sun,mou,tue,wed,thu,fri,sat}a,b,c;2、枚舉類型的變量賦值和使用枚舉類型在使用中有以下規定:枚舉值是常量,不是變量。不能在程序中用賦值語句再對它賦值。例如對枚舉weekday的元素再作以下賦值:sun=5;mon=2;sun=mon;都是錯誤的。枚舉元素本身由系統定義了一個表示序號的數值,從0開始順序定義為0,1,2…。如在weekday中,sun值為0,mon值為1,…,sat值為6。【例7-19】枚舉類型賦值。main(){enumweekday{sun,mon,tue,wed,thu,fri,sat}a,b,c;
a=sun;b=mon;c=tue;
printf("%d,%d,%d",a,b,c);}說明:只能把枚舉值賦予枚舉變量,不能把元素的數值直接賦予枚舉變量。如:a=sum;b=mon;是正確的。而:a=0;b=1;是錯誤的。如一定要把數值賦予枚舉變量,則必須用強制類型轉換。如:a=(enumweekday)2;其意義是將順序號為2的枚舉元素賦予枚舉變量a,相當于:a=tue。還應該說明的是枚舉元素不是字符常量也不是字符串常量,使用時不要加單、雙引號。【例7-20】枚舉類型的使用。main(){enumbody{a,b,c,d}month[31],j;inti;j=a;for(i=1;i<=30;i++){month[i]=j;j++;if(j>d)j=a;}for(i=1;i<=30;i++){switch(month[i]){casea:printf("%2d%c\t",i,'a');break;caseb:printf("%2d%c\t",i,'b');break;casec:printf("%2d%c\t",i,'c');break;cased:printf("%2d%c\t",i,'d');break;default:break;}}printf("\n");}7.9.1用typedef說明一種新類型
在C語言程序中,除了可以直接使用C提供的標準類型名(int,char,float,double,long等),和自己聲明的結構體,共用體,指針,枚舉類型外,還可以用typedef聲明新的類型名來代替已有的類型名。功能:用自定義名字為已有數據類型命名簡單形式:
typedeftypename
newname;類型定義語句關鍵字已有數據類型名用戶定義的類型名7.9typedef的用法說明:1.typedef沒有創造新數據類型2.typedef是定義類型,不能定義變量3.typedef與define不同
definetypedef預編譯時處理編譯時處理簡單字符置換為已有類型命名
例typedeffloatREAL;類型定義后,與已有類型一樣使用例INTEGERa,b,c;REALf1,f2;
inta,b,c;floatf1,f2;例typedefintINTEGER;例定義數組類型
inta[100];intARRAY[100];typedefintARRAY[100];ARRAYa,b,c;
inta[100],b[100],c[100];7.10結構體和共同體數據綜合應用舉例1、結構體數據綜合應用【例7-21】計算學生的平均成績和不及格的人數。structstu_record{intnum;charname[20];floatscore;}stu[5]={{101,"Lijun",45},{102,"Zhangsan",62.5},{103,"Wangfang",92.5},{104,"Jiangling",87},{105,"Dengming",58},};//初始化結構體數組stuvoidmain(){inti,c=0;floatave,s=0;for(i=0;i<5;i++){s+=stu[i].score;if(stu[i].score<60)c+=1;}printf("s=%f\n",s);ave=s/5;printf("average=%f\ncount=%d\n",ave,c);}本例程序中定義了一個外部結構數組stu,共5個元素,并作了初始化
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 商場主體合同變更協議
- 咸魚售后協議書范本
- 總價下浮20合同協議
- 商品展示樣品合同協議
- 微信公眾號合同解約協議
- 毛呸房屋租賃合同協議
- 2025年度糧食委托競價采購合同書
- 售后責任協議書范本
- 2025高校科研技術服務合同
- 員工在病期間協議合同
- CHINET2024年全年細菌耐藥監測結果
- 膀胱癌健康宣教課件
- X線腰椎臨床意義
- 綻放的梨花(2024年山東濱州中考語文試卷記敘文閱讀試題)
- 2024-2025學年人教版英語七年級下冊Unit 5 Here and now Section B 1a - 1d 教案
- 中國銀行課件模板7
- DB3301T 1118-2023 秀珍菇設施栽培技術規程
- 美容院會員卡使用合約
- 中國郵政廣西分公司招聘筆試沖刺題2025
- 膏方課件培訓
- 浙江省精誠聯盟2024-2025學年高三上學期12月適應性聯考 政治試卷(含答案解析)
評論
0/150
提交評論