C語言程序設計課件第8章-結構、聯(lián)合、枚舉_第1頁
C語言程序設計課件第8章-結構、聯(lián)合、枚舉_第2頁
C語言程序設計課件第8章-結構、聯(lián)合、枚舉_第3頁
C語言程序設計課件第8章-結構、聯(lián)合、枚舉_第4頁
C語言程序設計課件第8章-結構、聯(lián)合、枚舉_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

C語言程序設計

2024/5/131第八章結構、聯(lián)合、枚舉主講:計算機學院內容提要本章介紹3種用戶自定義類型:結構、聯(lián)合、枚舉需要掌握這幾種用戶自定義類型的以下知識:為什么要定義這種類型,是為了適合何種數(shù)據存儲與處理需要的該類型定義的形式該類型的變量在內存中占用空間的形式及其訪問方式重點是結構類型,對該類型還應掌握以下知識:該類型的嵌套定義,其不同層次成員的訪問方式在結構中的同名問題結構數(shù)組與結構指針的使用(處理一批記錄)結構類型在函數(shù)中的使用:形參的設定,返回值等問題一些常用算法在結構中的實現(xiàn)(如排序)2024/5/133結構——類型定義為什么需要結構類型:有的時候需要一組相關的信息表示同一個對象,例如一個學生的信息包括:學號、姓名、性別、成績等,這些數(shù)據項的類型不一定一致,即使是同一種類型也會對應不同的意義,因此需要將它們作為一個變量的成員組成一個整體。此前所學的標準類型及數(shù)組和指針類型都無法滿足這一需求結構類型的定義格式:struct

結構類型名{ 結構體成員表列;};此關鍵字為定義結構類型的起始標志結構類型名必須是用戶自定義標識符一對大括號必須有,其間是該結構體類型的各個成員必須以分號結束成員列表的形式:成員類型名成員名;相同類型的成員名可以共用一個成員類型名2024/5/134結構——類型定義結構類型的定義舉例:structDate //表示日期的結構{

intyr;//年

intmo;//月

int

da;//日};structStudent//表示學生信息的結構{longunsignedid;//學號doublegrades; //成績};intyr,mo,da;

//年月日類型相同可用一個類型標識符類型不一致的成員必須分別定義2024/5/135結構變量的定義結構類型定義后,struct

結構類型名就作為結構類型名使用,可以定義該類型的變量,有3種形式:(1)先定義結構類型,再定義結構變量例:structDatedt;

structStudentst; (2)在定義結構類型的同時定義結構變量,結構類型名不省略,將結構變量名寫在結構類型定義結束的右大括號之后、分號之前例:structDate //不省略結構類型名{

int

yr,mo,da;//年、月、日}dt;//定義結構變量dt(3)結構類型名省略結構類型名2024/5/136用typedef定義結構類型別名用typedef可以為一個結構類型定義別名,以方便定義結構類型的變量,定義結構類型別名也有3種形式:(1)先定義結構類型,再定義結構類型的別名:例:typedef

structDateDate;

Date

dt; (2)在定義結構類型的同時定義其別名,結構類型名不省略,將結構類型別名寫在結構類型定義結束的右大括號之后、分號之前例:typedef

structDate //不省略結構類型名{

int

yr,mo,da;//年、月、日}Date;//定義結構類型別名Date(3)結構類型名省略結構類型名給已經定義的類型structDate定義一個類型別名Date

直接用Date作為結構類型名定義一個結構變量dt2024/5/137結構變量的訪問結構變量的初始化:與其他類型的變量類似,結構變量在定義時也可以進行初始化,常用兩種方式:(1)將初值用一對大括號括起,依次列出各個成員的值,所列出的值可以少于成員個數(shù),默認用0填充例:Datedt1={2005,8,16};Datedt2={2009,4};(2)兩個類型一致的結構變量可以用一個為另一個初始化例:Datedt4,dt3=dt1;

結構變量在定義之后,可進行賦值,滿足以下要求:(1)兩個類型一致的結構變量可以用一個為另一個賦值(2)注意:結構變量定義之后,不能再用各個成員的值給結構變量作整體賦值相當于:

Datedt2={2009,4,0};用dt1來初始化dt3,這里的dt4未初始化例:dt4=dt1;例:

Datedt;dt={2005,8,16};X

2024/5/138結構變量成員的訪問結構變量占用內存的方式:與數(shù)組很類似,一個結構變量的各個成員在內存中依次占用地址相鄰的內存單元,因此一個結構變量所占的空間至少為其各個成員所需的內存空間之和結構變量與其成員的關系:結構變量是一組(成員)變量的整體標志,是“外衣”,其中的每一個成員變量(簡稱成員)都是這個整體中的成分。引用結構變量成員的方式:必須從結構變量名開始,在其后加成員引用運算符“.”,再加成員名:例:Datedt1={2005,8,16};相當于:dt1.yr=2005;dt1.mo=8;dt1.da=16;2024/5/139結構變量成員的訪問程序8.1結構變量成員的引用示例該例中用到了前面例子中的兩個結構體類型:structStudent//表示學生信息的結構{longunsignedid;//學號floatgrades; //成績};structDate //表示日期的結構{

int

yr,mo,da;};動態(tài)演示過程2024/5/1310結構指針結構指針的概念:就是基類型為結構類型的指針,只能獲得基類型一致的結構類型變量的地址.結構指針的定義形式:結構類型名*結構指針變量名;通過結構指針引用結構成員的兩種等價方式:(1)

(*結構指針).結構成員(2)結構指針->結構成員例:

Students;

Student*ps=&s; //指向結構s的指針ps

ps->id=2005065; //相當于(*ps).id=2005065;ps->grades=90.5; //相當于(*ps).grades=90.5;這里的Student是用typedef定義過的結構體類型別名2024/5/1311結構數(shù)組結構數(shù)組的概念:就是基類型為結構類型的數(shù)組,因為數(shù)組類型并未規(guī)定其基類型必須是什么類型,事實上可以是任何類型結構數(shù)組的定義形式:結構類型名

結構數(shù)組名;通過結構數(shù)組引用結構成員的3種方式:(1)結構數(shù)組名[下標].結構成員(2)(*(結構數(shù)組名+下標)).結構成員(3)(結構數(shù)組名+下標)->結構成員例: Studentsa[3];

sa[i].id //第i+1個學生的學號

sa[i].grades //第i+1個學生的成績這里的Student是用typedef定義過的結構體類型別名方式1(*(sa+i)).id(*(sa+i)).grades

方式2(sa+i)->id(sa+i)->grades

方式32024/5/1312結構數(shù)組結構數(shù)組可以初始化,方法是:每個數(shù)組元素的各個分量用第二層括號的括起。例:Studentsa[3]={{1001,80},{1002,89},{1003,90}};

結構數(shù)組在內存中的存放方式:占用一組地址連續(xù)的空間,數(shù)組元素相鄰,元素的各成員相鄰100180100289100390sa[0].idsa[0].gradessa[1].idsa[1].gradessa[2].idsa[2].grades程序8.2從鍵盤上輸入3個學生記錄,并在屏幕輸出動態(tài)演示過程(請在VC++下運行)2024/5/1313結構的嵌套結構嵌套的概念:結構的成員可以是任何類型,當然也可以是結構類型,這樣就形成了結構的嵌套結構嵌套的定義形式:(1)先定義”小”的結構類型,再在”大”的結構類型中用其作為某成中類型名(2)將小結構類型的定義嵌套在大的結構類型定義中例:

structDate {

int

yr,mo,da;};

typedef

structDateDate;

structStudent {longunsignedid;doublegrades;

Datedt;//入學日期dt

};

typedef

structStudent

Student;

方式1

structDate {

int

yr,mo,da;}dt;方式22024/5/1314結構的嵌套程序8.3:用結構嵌套定義一個學生結構,從鍵盤上輸入3個學生記錄,并在屏幕輸出。主函數(shù)輸入部分主要代碼:(輸出的代碼類似)inti;Studentsa[3];printf("Enter3records:\n");for(i=0;i<3;i++)//輸入3個學生的各項信息{

scanf("%Lu%Lf",&sa[i].id,&sa[i].grades);

scanf("%d/%d/%d",&sa[i].dt.yr,&sa[i].dt.mo,&sa[i].dt.da);}動態(tài)演示過程2024/5/1315結構型返回值和地址調用

結構類型也可以作為返回類型根據第6章有返回值的函數(shù)調用過程中經過3次賦值的知識,結構類型作為函數(shù)返回類型顯然是低效的結構變量由很多成員組成,一般占用空間較大這就意味著臨時變量的空間較大,賦值也需要時間因此一般將返回值類型改為void型,而增設一個結構類型的指針形參,通過間接引用修改對應實參結構體變量的值。下面的動態(tài)演示展示了二者的區(qū)別與效率差異本例再一次體現(xiàn)出指針的高效性動態(tài)演示過程2024/5/1316結構應用舉例---學生記錄排序分析:一組學生記錄,首先要定義一維數(shù)組,該數(shù)組的元素類型為結構類型,因此本題需定義一維結構數(shù)組排序算法:第6章所學的排序算法在這里都可以使用,只是在元素互相交換時,體現(xiàn)為結構體變量的交換函數(shù)參數(shù)的選擇:由第6章的知識,本題形參用一級指針最高效,指針的基類型就是一維數(shù)組的基類型模塊的劃分:定義一個輸入函數(shù)、排序函數(shù)、輸出函數(shù),主函數(shù)定義一維結構數(shù)組作為實參,依次調用這3個函數(shù)完成整個程序結構類型:本例的結構類型就是前面一直介紹的Student類型,包括學號和成績兩個域2024/5/1317結構應用舉例---學生記錄排序讀入部分:見動態(tài)演示排序算法:voidSelectSort(Student*pa,intn)//選擇排序{

int

i,j,min; Studenttemp;//定義結構臨時變量

for(i=0;i<n-1;i++) //控制n-1趟循環(huán)

{ min=i; //用min記下本趟分數(shù)最小元素的下標

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

if(pa[j].grades<pa[min].grades)min=j;

if(min!=i)//如果分數(shù)最小元素未到位,交換元素

{temp=pa[i];

pa[i]=pa[min];

pa[min]=temp; } }}動態(tài)演示過程完整程序請上機運行2024/5/1318結構應用舉例---洗牌程序8.5

洗牌程序。假設洗牌之前52張撲克牌按照紅桃、方塊、梅花和黑桃四種花色的順序,每種花色又是按照從1到13的順序排列。通過產生隨機數(shù)模擬洗牌,每一張牌與隨機選定的一張牌調換,從而打亂最初的次序。問題分析:(1)每張撲克牌用哪些信息可以完整表示---花色+點數(shù)結構類型的定義:structCard{ charsuit; //記錄花色

intpips; //記錄點數(shù)};typedef

structCardCard;2024/5/1319結構應用舉例---洗牌(2)所有撲克牌信息的存儲需要用一維結構數(shù)組結構數(shù)組的定義:Carddeck[52];(3)初始信息的表示:52張牌最初按紅桃、方塊、梅花和黑桃四種花色的順序,每種花色又按照從1到13的順序排列for(i=0;i<52;i++){

deck[i].suit=i/13+3;//賦花色的ASCII碼

deck[i].pips=i%13+1;//賦每張牌的點數(shù)}(4)關鍵的步驟,如何實現(xiàn)模擬洗牌?編寫洗牌函數(shù)Shuffle(structCard*p,intn)。通過一個循環(huán),每一張牌與隨機選定的一張牌調換。紅桃、方塊、梅花和黑桃的ASCII碼分別是3、4、5和6調用隨機函數(shù)產生0~51之間的隨機數(shù)作為第幾張牌序號2024/5/1320結構應用舉例---洗牌(2)所有撲克牌信息的存儲需要用一維結構數(shù)組結構數(shù)組的定義:Carddeck[52];(3)初始信息的表示:52張牌最初按紅桃、方塊、梅花和黑桃四種花色的順序,每種花色又按照從1到13的順序排列for(i=0;i<52;i++){

deck[i].suit=i/13+3;//賦花色的ASCII碼

deck[i].pips=i%13+1;//賦每張牌的點數(shù)}(4)關鍵的步驟,如何實現(xiàn)模擬洗牌?編寫洗牌函數(shù)Shuffle(structCard*p,intn)。通過一個循環(huán),每一張牌與隨機選定的一張牌調換。紅桃、方塊、梅花和黑桃的ASCII碼分別是3、4、5和6調用隨機函數(shù)產生0~51之間的隨機數(shù)作為第幾張牌序號2024/5/1321結構應用舉例---洗牌洗牌函數(shù):voidShuffle(Card*pa,intn){

int

i,j; structCardtemp;srand(time(0)); //使隨機函數(shù)值隨時間變化

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

{ j=rand()%n;//隨機選擇一張牌與當前牌i調換

temp=pa[i];//與當前牌調換

pa[i]=pa[j];

pa[j]=temp;

}}動態(tài)演示過程完整程序請上機運行2024/5/1322聯(lián)合——類型定義為什么需要聯(lián)合類型:有如果一組數(shù)據分別屬于不同的類型,而每次處理僅訪問其中一種類型的數(shù)據,那么為了節(jié)省存儲資源,這組數(shù)據可以共享一段空間,這就需要定義聯(lián)合類型的變量。聯(lián)合類型的定義格式:union聯(lián)合類型名{ 聯(lián)合中的成員表列;};聯(lián)合類型變量的定義方式與結構一樣,也有3種:先定義類型后定義變量、定義類型的同時定義變量(類型名不缺省和缺省都可以)此關鍵字為定義聯(lián)合類型的起始標志聯(lián)合類型名必須是用戶自定義標識符一對大括號必須有,其間是該聯(lián)合類型的各個成員必須以分號結束成員列表的形式:成員類型名成員名;相同類型的成員名可以共用一個成員類型名2024/5/1323聯(lián)合——類型及變量的定義聯(lián)合類型及變量的定義舉例:unionUNI //定義聯(lián)合類型{charch;floatx;};typedefunionUNIUNI;//定義類型別名UNIu; //定義聯(lián)合類型變量聯(lián)合變量的成員占用內存方式:聯(lián)合變量的成員共享空間,變量所占內存的大小等于其最大的1個成員空間大小----空間共享聯(lián)合空間只有一個最新賦的成員值有效,后來的值覆蓋前面的值----后來為主u.x(占4字節(jié))u.ch(占1字節(jié))2024/5/1324聯(lián)合變量的訪問聯(lián)合變量的初始化:與其他類型的變量類似,聯(lián)合變量在定義時也可初始化,但只能初始化第一個成員UNIu={'A'}; //合法UNIu={'A',3.14}; //非法UNIu={3.14}; //告警,將3.14轉化為字符型時信息丟失不能對聯(lián)合變量整體賦值、只能對成員實施讀、寫或運算“=”對成員也用點運算符,方式同結構成員的訪問,例:u.x=3.1415F;

//合法u={3.1415F}; //非法u.ch='B';//合法u={'B'}; //非法2024/5/1325聯(lián)合應用舉例程序8.6

聯(lián)合類型的定義及使用簡單示例(主函數(shù))...............................intmain(){UNIu; printf("Inputarealnumber:");

scanf("%f",&u.x); printf(“u.ch=%c,u.x=%f\n”,u.ch,u.x);

getchar();//跳過回車符

printf("Inputacharacter:");

scanf("%c",&u.ch); printf("u.ch=%c,u.x=%f\n",u.ch,u.x);

return0;}動態(tài)演示過程2024/5/1326聯(lián)合與結構兩種類型最本質的區(qū)別:結構變量的所有成員在內存中依次占用空間,所需空間至少為各成員空間大小之和;而聯(lián)合變量的所有成員共享一段內存空間,所需空間為占空間最大的成員所需空間訪問聯(lián)合成員的方式與訪問結構成員的方式完全相同對聯(lián)合變量的其中一個成員讀入或賦值以后,可以訪問其它成員,但顯示結果是將在內存中01序列解釋為所訪問成員類型的值。

聯(lián)合數(shù)組、聯(lián)合指針的意義與結構數(shù)組、結構指針類似隨著硬件技術的提高,已不必通過定義聯(lián)合類型節(jié)省內存空間,因此聯(lián)合類型在編程時用得并不廣泛2024/5/1327枚舉——類型及變量的定義為什么需要枚舉類型:有時候解決問題,為了用直觀形象的標識符來表示一個類型中的有限個常量值,需要定義枚舉類型。例如:一年四季用Spring、Summer、Autumn、Winter比直接用1、2、3、4更加直觀。枚舉類型的定義格式:e

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論