版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
在線(xiàn)教務(wù)輔導(dǎo)網(wǎng):://教材其余課件及動(dòng)畫(huà)素材請(qǐng)查閱在線(xiàn)教務(wù)輔導(dǎo)網(wǎng)QQ:349134187
或者直接輸入下面地址:第8章結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析C語(yǔ)言編程技巧分析本章概述本章首先簡(jiǎn)單介紹結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表的相關(guān)知識(shí),接著詳細(xì)講解運(yùn)用結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)時(shí)需要注意的問(wèn)題,并通過(guò)實(shí)例分析運(yùn)用結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)的一些編程技巧。本章的學(xué)習(xí)目標(biāo)本章教學(xué)目的:
掌握結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí);理解運(yùn)用結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)時(shí)需要注意的一些問(wèn)題;掌握結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)的相關(guān)編程技巧。本章教學(xué)重點(diǎn):
運(yùn)用結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)需注意的問(wèn)題和編程技巧。本章教學(xué)難點(diǎn):
關(guān)于結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)的編程技巧。8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.2運(yùn)用結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)時(shí)需要注意的問(wèn)題8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)編程技巧分析本章主要內(nèi)容8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.1結(jié)構(gòu)體1、結(jié)構(gòu)體類(lèi)型的聲明struct結(jié)構(gòu)體名{
成員項(xiàng)表列;};例如:structSTU/*聲明一個(gè)結(jié)構(gòu)體類(lèi)型,名稱(chēng)是structSTU*/{longxh[11];/*xh是一個(gè)成員,存放學(xué)號(hào)*/charxm[20];/*xm是一個(gè)成員,存放姓名*/charbj[20];/*bj是一個(gè)成員,存放班級(jí)*/floatcj[3];/*cj是一個(gè)成員,存放三科考試成績(jī)*/};8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.1結(jié)構(gòu)體2、結(jié)構(gòu)體類(lèi)型變量的定義結(jié)構(gòu)體類(lèi)型變量的定義可以有以下三種形式:(1)先聲明結(jié)構(gòu)體類(lèi)型,再定義結(jié)構(gòu)體類(lèi)型的變量。例如利用上面的structSTU結(jié)構(gòu)體類(lèi)型,可以在下面定義structSTU類(lèi)型的變量:structSTUstudent1,student2(2)聲明結(jié)構(gòu)體類(lèi)型同時(shí)定義結(jié)構(gòu)體類(lèi)型變量:structDATE/*日期結(jié)構(gòu)體類(lèi)型*/{intday;
intmonth;
intyear;}time1,time2;/*定義兩個(gè)structDATE類(lèi)型變量*/8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.1結(jié)構(gòu)體(3)直接定義結(jié)構(gòu)體類(lèi)型變量:struct{floatre;/*復(fù)數(shù)的實(shí)部*/floatim;/*復(fù)數(shù)的虛部*/}a,b;/*定義兩個(gè)復(fù)數(shù)型變量*/3、結(jié)構(gòu)體成員的引用結(jié)構(gòu)體成員的引用格式如下:<結(jié)構(gòu)體類(lèi)型變量名>.<成員名>如:a.re=2;a.im=2.5;time1.day=23;time2.month=12;strcpy(student1.xm,〞張三〞);8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.1結(jié)構(gòu)體4、結(jié)構(gòu)體類(lèi)型變量的初始化上述對(duì)結(jié)構(gòu)體類(lèi)型變量的三種定義形式均可在定義時(shí)初始化,例如:structSTUstudent={1213012,"李強(qiáng)","英語(yǔ)1班",98.5,97.4,95};5、結(jié)構(gòu)體類(lèi)型的數(shù)組結(jié)構(gòu)體類(lèi)型數(shù)組的定義與其它數(shù)據(jù)類(lèi)型數(shù)組的定義方式一樣,例如:structSTUclass[50];
/*定義一個(gè)50個(gè)元素的結(jié)構(gòu)體數(shù)組*/引用結(jié)構(gòu)體類(lèi)型數(shù)組元素的成員的格式:<結(jié)構(gòu)體類(lèi)型數(shù)組名><[下標(biāo)]>.<成員>例如:class[i].xm表示第i個(gè)學(xué)生的姓名,
class[i].bj表示第i個(gè)學(xué)生的班級(jí)。
8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.1結(jié)構(gòu)體6、結(jié)構(gòu)體類(lèi)型的指針變量結(jié)構(gòu)體類(lèi)型的指針變量的定義格式如下:struct
結(jié)構(gòu)體類(lèi)型名*變量名;例如:structSTUstudent1,*p=&student1;可以通過(guò)結(jié)構(gòu)體指針變量間接訪問(wèn)結(jié)構(gòu)變量的各個(gè)成員。其訪問(wèn)的格式為:(*結(jié)構(gòu)體指針變量).成員名或結(jié)構(gòu)體指針變量->成員名例如:(*p).xh
或者p->xh
等價(jià)于student1.xh
注意:(*p)兩側(cè)的括號(hào)不可少。8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.2共用體1、共用體類(lèi)型的聲明和共用體類(lèi)型變量的定義共用體類(lèi)型的聲明與結(jié)構(gòu)體類(lèi)型的聲明類(lèi)似,格式如下:union共用類(lèi)型名{成員列表};共用變量的定義與結(jié)構(gòu)變量的定義類(lèi)似,三種格式如下:直接定義:
間接定義:
省略類(lèi)型名直接定義:union共用體名union共用體名
union{成員列表{成員列表};
{成員列表}變量列表;
union共用體名變量列表;}變量列表;
8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.2共用體2、共用體變量的引用引用形式與結(jié)構(gòu)體變量一樣,只能逐個(gè)引用共用體變量的成員。注意:不能對(duì)共用體變量進(jìn)行整體的輸入或輸出。假設(shè)a是共用體類(lèi)型變量,那么下面語(yǔ)句都是錯(cuò)誤的:scdanf(“%d〞,&a);printf(“%d〞,a);訪問(wèn)共用體類(lèi)型變量a成員的格式與訪問(wèn)結(jié)構(gòu)體變量成員格式相同,假設(shè)i是a的一個(gè)int型成員,那么下面的輸入或輸出格式是正確的:scanf(“%d〞,&a.i);printf(“%d\n〞,a.i);8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.2共用體3、共用體與結(jié)構(gòu)體相似之處〔1〕都是由不同類(lèi)型的數(shù)據(jù)項(xiàng)組合在一起;〔2〕都只能對(duì)分量進(jìn)行操作和引用。4、共用體變量的特點(diǎn)〔1〕系統(tǒng)采用覆蓋技術(shù),實(shí)現(xiàn)共用體變量各成員的內(nèi)存共享,所以在某一時(shí)刻,存放在內(nèi)存中的和起作用的是最后一次存入的成員值。共用體變量占用的內(nèi)存空間,等于最長(zhǎng)的成員的長(zhǎng)度,而不是各成員長(zhǎng)度之和?!?〕由于所有成員共享同一內(nèi)存空間,故共用體變量的地址與各成員的地址相同?!?〕不能對(duì)共用體變量進(jìn)行初始化〔而結(jié)構(gòu)體變量可以初始化〕;也不能將共用體變量作為函數(shù)參數(shù),以及使函數(shù)返回一個(gè)共用體數(shù)據(jù),但可以使用指向共用體變量的指針?!?〕共用類(lèi)型可以出現(xiàn)在結(jié)構(gòu)類(lèi)型定義中,反之亦然。8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.3枚舉類(lèi)型1、枚舉類(lèi)型的聲明enum枚舉類(lèi)型名{取值表};例如enumweekdays{Sun,Mon,Tue,Wed,Thu,Fri,Sat};上面括號(hào)中的標(biāo)識(shí)符稱(chēng)為枚舉常量。它只能為標(biāo)識(shí)符,不能為數(shù)字常量或字符常量。2、枚舉變量的定義枚舉變量的定義與結(jié)構(gòu)體變量類(lèi)似,有下面一些定義形式:〔1〕間接定義,例如:enumweekdaysw1,w2;〔2〕直接定義,例如:enumweekdays{Sun,……}w1,w2;〔3〕省略類(lèi)型名直接定義枚舉變量,例如:enum{Sun,Mon,Tue,Wed,Thu,Fri,Sat}w3,w4;8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.4鏈表鏈表是動(dòng)態(tài)地進(jìn)行存儲(chǔ)分配的一種結(jié)構(gòu),鏈表中的數(shù)據(jù)在內(nèi)存中不必連續(xù)存放,數(shù)據(jù)之間通過(guò)指針鏈接起來(lái),相比于數(shù)組結(jié)構(gòu),鏈表的插入和刪除操作比較方便。1、鏈表中的結(jié)點(diǎn)鏈表中的結(jié)點(diǎn)是結(jié)構(gòu)體類(lèi)型的數(shù)據(jù),每個(gè)結(jié)點(diǎn)的所有成員分為兩局部,一局部用來(lái)存放數(shù)據(jù)〔各種實(shí)際的信息〕,如編號(hào)、姓名和年齡等;另一局部存放指針,用來(lái)連接其它結(jié)點(diǎn)。例如:定義了一個(gè)結(jié)構(gòu)體類(lèi)型變量a,成員num、name和score用來(lái)存放數(shù)據(jù)〔各種實(shí)際的信息〕,成員next用來(lái)存放指針〔指向下一個(gè)結(jié)點(diǎn)的首地址〕。structNODE{intnum;charname[10];intage;structNODE*next;}a;8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.4鏈表2、鏈表的種類(lèi):〔1〕單向鏈表:每個(gè)結(jié)點(diǎn)除了一些數(shù)據(jù)成員外,只包含一個(gè)指針成員。單向鏈表通常有一個(gè)頭指針〔head),用于指向鏈表頭。單向鏈表有一個(gè)尾結(jié)點(diǎn),尾結(jié)點(diǎn)的指針成員存放的是空指針〔NULL〕。〔2〕循環(huán)鏈表:最后一個(gè)結(jié)點(diǎn)的指針指向該循環(huán)鏈表的第一個(gè)結(jié)點(diǎn)或者表頭結(jié)點(diǎn),從而構(gòu)成一個(gè)環(huán)形的鏈?!?〕雙向鏈表:結(jié)點(diǎn)除含有數(shù)據(jù)成員外,還有兩個(gè)指針成員,一個(gè)指針成員存儲(chǔ)直接后繼結(jié)點(diǎn)地址;另一個(gè)指針成員存儲(chǔ)直接前驅(qū)結(jié)點(diǎn)地址。8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.4鏈表3、單向鏈表的根本操作:〔1〕創(chuàng)立鏈表:從無(wú)到有地建立起一個(gè)鏈表,即往空鏈表中依次插入假設(shè)干結(jié)點(diǎn),并保持結(jié)點(diǎn)之間的前驅(qū)和后繼關(guān)系?!?〕查找結(jié)點(diǎn):按給定的結(jié)點(diǎn)索引號(hào)或查找條件,查找某個(gè)結(jié)點(diǎn)。〔3〕插入操作:在結(jié)點(diǎn)a與b之間插入一個(gè)新的結(jié)點(diǎn)d?!?〕刪除操作:將結(jié)點(diǎn)a與b之間的結(jié)點(diǎn)d刪除。〔5〕打印輸出:輸出結(jié)點(diǎn)的數(shù)據(jù)成員值。8.1結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表知識(shí)簡(jiǎn)要介紹8.1.4鏈表4、處理動(dòng)態(tài)鏈表所需的函數(shù):〔1〕void*malloc(unsignedintsize);作用:在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配一個(gè)長(zhǎng)度為size的連續(xù)空間?!?〕void*calloc(unsignedn,unsignedsize);作用:在內(nèi)存動(dòng)態(tài)區(qū)中分配n長(zhǎng)度為size的連續(xù)空間。〔3〕void*realloc(void*mem_address,unsignedintnewsize);作用:擴(kuò)大mem_address指向的內(nèi)存塊的大小為newsize?!?〕voidfree(void*p);作用:釋放由p指向的內(nèi)存區(qū)。8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于結(jié)構(gòu)體和共用體的類(lèi)型聲明〔1〕區(qū)分開(kāi)類(lèi)型名與變量名結(jié)構(gòu)體類(lèi)型名和結(jié)構(gòu)體變量名是兩個(gè)不同的概念,不能混淆。結(jié)構(gòu)體類(lèi)型名只能表示一個(gè)結(jié)構(gòu)形式,編譯系統(tǒng)并不對(duì)它分配內(nèi)存空間。只有當(dāng)某變量被說(shuō)明為這種類(lèi)型的結(jié)構(gòu)時(shí),才對(duì)該變量分配存儲(chǔ)空間。〔2〕結(jié)構(gòu)體與共用體可以相互引用C語(yǔ)言在聲明某個(gè)結(jié)構(gòu)體類(lèi)型或共用體類(lèi)型時(shí),可以使用已經(jīng)聲明過(guò)的結(jié)構(gòu)體、共用體類(lèi)型。結(jié)構(gòu)體類(lèi)型中可以有共用體類(lèi)型的成員,共用體類(lèi)型中可以有結(jié)構(gòu)體類(lèi)型的成員。例如:8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于結(jié)構(gòu)體和共用體的類(lèi)型聲明structdata{intday;intmouth;intyear;};structperson{charname[20];structdatabirthday;/*成員birthday的類(lèi)型structdata已經(jīng)在前面聲明過(guò)*/union{chardepartment[50];/*假設(shè)為教師身份時(shí),成員category為department*/intclass;/*假設(shè)為學(xué)生身份時(shí),成員category為class*/}category;/*成員category是共用體類(lèi)型*/}x;8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于結(jié)構(gòu)體和共用體的類(lèi)型聲明〔3〕typedef與結(jié)構(gòu)體的聯(lián)合應(yīng)用使用typedef命令可以取一個(gè)新的類(lèi)型名來(lái)代替已有的類(lèi)型名,一般當(dāng)有復(fù)雜類(lèi)型定義時(shí),如定義結(jié)構(gòu)體類(lèi)型、共用體類(lèi)型時(shí),常常用typedef為剛定義的復(fù)雜類(lèi)型取一個(gè)較為簡(jiǎn)單、直接的類(lèi)型名。例如:typedefstructnode{longnum;charname[10];structnode*next;}NODE,*LINK;
8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于結(jié)構(gòu)體和共用體的類(lèi)型聲明上面聲明了一個(gè)內(nèi)容與structnode相同但名為NODE的結(jié)構(gòu)體類(lèi)型名,還聲明了一個(gè)結(jié)構(gòu)體指針類(lèi)型LINK。注意,LINK不是指針變量,而是一個(gè)指針類(lèi)型。以下定義變量的形式都正確:
structnodestu1,*p;/*定義結(jié)構(gòu)體變量stu1和指針變量p*/NODEstu2,*q;/*定義結(jié)構(gòu)體變量stu2和指針變量q*/LINKr;/*定義結(jié)構(gòu)體指針變量r*/8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于結(jié)構(gòu)體和共用體的類(lèi)型聲明〔4〕不能遞歸定義在定義鏈表的結(jié)點(diǎn)類(lèi)型時(shí)常常用結(jié)構(gòu)體類(lèi)型本身去定義一個(gè)指針?lè)至?,如前面例子中的next分量,通過(guò)這個(gè)分量,使鏈表中的結(jié)點(diǎn)鏈接起來(lái),這是允許的,也是必須的。但是絕對(duì)不能用結(jié)構(gòu)體類(lèi)型自己去定義自己的一個(gè)非指針類(lèi)型分量,也就是不能遞歸定義。如下是錯(cuò)誤的:structnode{……;structnodenext;};
8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于結(jié)構(gòu)體、共用體變量的輸入和輸出結(jié)構(gòu)體、共用體類(lèi)型變量的輸入和輸出,必須采用變量的各成員獨(dú)立輸入輸出,而不能將結(jié)構(gòu)體、共用體類(lèi)型變量以整體的形式輸入輸出。可以通過(guò)C語(yǔ)言提供的輸入輸出函數(shù)完成對(duì)結(jié)構(gòu)體、共用體類(lèi)型變量成員的輸入輸出。結(jié)構(gòu)體、共用體變量各成員的數(shù)據(jù)類(lèi)型通常是不一樣的,為了統(tǒng)一輸入過(guò)程,可以先將變量的各成員均以字符串形式輸入,然后利用C語(yǔ)言的類(lèi)型轉(zhuǎn)換函數(shù)將其轉(zhuǎn)換為所需類(lèi)型。8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于結(jié)構(gòu)體、共用體變量的輸入和輸出類(lèi)型轉(zhuǎn)換的函數(shù)是:int
atoi(char*str);/*轉(zhuǎn)換str所指向的字符串為整型*/doubleatof(char*str);/*轉(zhuǎn)換str所指向的字符串為實(shí)型,*/longatol(char*str);/*轉(zhuǎn)換str所指向的字符串為長(zhǎng)整型*/
使用上述函數(shù),要包含頭文件"stdlib.h"。對(duì)上述的結(jié)構(gòu)體類(lèi)型structnode的變量student的成員輸入采用的一般形式:chartemp[20];
gets(student.xm);/*輸入結(jié)構(gòu)體變量的成員xm的值*/gets(temp);student.xh=atol(temp);/*轉(zhuǎn)換為長(zhǎng)整型后賦值*/for(i=0;i<3;i++)
{gets(temp);
student.cj[i]=atoi(temp);/*轉(zhuǎn)換為整型后賦值*/}8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于共用體與結(jié)構(gòu)體的主要區(qū)別〔1〕結(jié)構(gòu)體變量占用空間是各成員所占空間之總和;共用體變量占存儲(chǔ)空間是各成員中所占空間最大者?!?〕結(jié)構(gòu)體變量各成員占用內(nèi)存中一片連續(xù)的存儲(chǔ)區(qū),各成員的地址互不相同;共用體變量各成員在內(nèi)存中所占空間的起始地址相同?!?〕結(jié)構(gòu)體變量的各個(gè)分量在任何時(shí)刻都同時(shí)存在,且可同時(shí)引用。共用體變量的各個(gè)分量在某一時(shí)刻只存在其中一個(gè),也只能引用其中的一個(gè)?!?〕結(jié)構(gòu)體變量可以初始化,共用體變量不能初始化。8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題8.2.4關(guān)于結(jié)構(gòu)體與函數(shù)〔1〕結(jié)構(gòu)體作函數(shù)參數(shù)將一個(gè)結(jié)構(gòu)體變量的值傳遞給另一個(gè)函數(shù),可以采用兩種方式:用結(jié)構(gòu)體變量作參數(shù),形參與實(shí)參都用結(jié)構(gòu)體變量,參數(shù)傳遞時(shí)直接將實(shí)參結(jié)構(gòu)體變量的各個(gè)成員的值全部傳遞給形參的結(jié)構(gòu)體變量。注意:這種方式是按傳值方式傳遞參數(shù)的,函數(shù)中形參結(jié)構(gòu)體變量的修改不影響實(shí)參結(jié)構(gòu)體變量的值;這種方法要將全部成員值一個(gè)一個(gè)傳遞,開(kāi)銷(xiāo)大,因此一般不采用。用指向結(jié)構(gòu)體的指針作函數(shù)參數(shù),形參為結(jié)構(gòu)體類(lèi)型的指針變量,實(shí)參為結(jié)構(gòu)體變量〔或數(shù)組〕的地址或指向結(jié)構(gòu)體變量〔數(shù)組〕的指針。這種方式只傳遞地址,不傳遞結(jié)構(gòu)體變量的值,克服了第一種方法的缺點(diǎn),實(shí)際編程中被較多采用。8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于結(jié)構(gòu)體與函數(shù)〔2〕結(jié)構(gòu)體作函數(shù)的返回值與結(jié)構(gòu)體作函數(shù)參數(shù)相類(lèi)似,既可以設(shè)置函數(shù)的返回值為結(jié)構(gòu)體類(lèi)型的,也可以設(shè)置函數(shù)的返回值為結(jié)構(gòu)體指針類(lèi)型的。前者在運(yùn)行時(shí)會(huì)有較多的數(shù)據(jù)復(fù)制,不利于提高程序的效率;后者只傳遞指針,開(kāi)銷(xiāo)小,效率高,多為程序設(shè)計(jì)者所采用。8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題8.2.5關(guān)于枚舉類(lèi)型〔1〕枚舉類(lèi)型僅適用于取值有限的數(shù)據(jù)。例如:1周的7天,1年的12個(gè)月?!?〕取值表中的值為枚舉元素,其含義由程序解釋。例如,不是寫(xiě)成“Sun〞就自動(dòng)代表“星期天〞。事實(shí)上,枚舉元素用什么表示都可以?!?〕枚舉類(lèi)型變量w1,w2只能在定義的取值表中取其中一個(gè)枚舉常量作為當(dāng)前值?!?〕枚舉元素作為常量是有值的,假設(shè)無(wú)特殊規(guī)定,枚舉元素的值是定義時(shí)的順序號(hào)。定義時(shí)的順序號(hào),從0開(kāi)始,依次增1。所以枚舉元素可以進(jìn)行比較,比較規(guī)那么是:序號(hào)大者為大。例如,上例中的Sun=0、Mon=1、……、Sat=6,所以Mon>Sun、Sat最大。8.2運(yùn)用結(jié)構(gòu)體、鏈表等知識(shí)時(shí)需要注意的問(wèn)題關(guān)于枚舉類(lèi)型〔5〕枚舉元素的值也是可以改變的??梢杂沙绦蛑付?,例如:enumweekdays{Sun=7,Mon=1,Tue,Wed,Thu,Fri,Sat};那么Sun=7,Mon=1,從Tue=2開(kāi)始,依次增1?!?〕一個(gè)整型數(shù)值不能直接賦值給一個(gè)枚舉變量。enumweekdays{Sun=7,Mon=1,Tue,Wed,Thu,Fri,Sat};enumweekdayswk1;不允許直接賦值整數(shù):wk1=7;/*數(shù)據(jù)類(lèi)型不同*/只能寫(xiě)成:wk1=Sun;或wk1=(enumweekdays)7;甚至可以是表達(dá)式,如:w2=(enumweekday)(5-3);8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析例8.1用結(jié)構(gòu)體類(lèi)型描述一個(gè)一元二次方程〔ax2+bx+c=0〕,并編寫(xiě)一個(gè)求其根的函數(shù)。程序如下:#include"stdio.h"#include"math.h"structfaction{floata;floatb;floatc;floatx1,x2;};intjie(structfaction*f){floatdel;del=(f->b)*(f->b)-4*(f->a)*(f->c);if(del>=0){f->x1=(-f->b+sqrt(del))/(2*f->a);f->x2=(-f->b-sqrt(del))/(2*f->a);return1;}elsereturn0;}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析main(){structfactionf1;intresult;printf("請(qǐng)輸入一個(gè)一元二次方程的三個(gè)系數(shù)");scanf("%f%f%f",&f1.a,&f1.b,&f1.c);result=jie(&f1);if(result=1)printf("x1=%f,x2=%f\n",f1.x1,f1.x2);elseprintf("無(wú)實(shí)數(shù)解");}分析:這個(gè)例子通過(guò)一個(gè)結(jié)構(gòu)體把一個(gè)一元二次方程相關(guān)的數(shù)據(jù)都封裝在一起,然后通過(guò)相應(yīng)的函數(shù)操作此數(shù)據(jù)對(duì)象,已具備初步的面向?qū)ο蟪绦蛟O(shè)計(jì)的思想。注意兩種引用結(jié)構(gòu)體成員的方法,在main函數(shù)中對(duì)f1成員的引用直接用f1.x1、f1.x2,而在jie函數(shù)中由于f是指針變量,故引用的方法是f->x1、f->x2等等。8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析例8.2輸入3名學(xué)生信息〔信息包括學(xué)號(hào)、姓名和計(jì)算機(jī)成績(jī)〕。然后輸出這3名學(xué)生信息,最后將其中成績(jī)最高的學(xué)生全部信息顯示在屏幕上。程序如下:第1種方法:使用普通的結(jié)構(gòu)體變量,每個(gè)學(xué)生的信息存放在一個(gè)變量中。#include<stdio.h>structstudents{longno;charname[10];intscore;};main(){structstudentss1,s2,s3,max;scanf("%ld%s%d",&s1.no,,&s1.score);scanf("%ld%s%d",&s2.no,,&s2.score);scanf("%ld%s%d",&s3.no,,&s3.score);8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析printf("%d%s%4d\n",s1.no,,s1.score);printf("%d%s%4d\n",s2.no,,s2.score);printf("%d%s%4d\n",s3.no,,s3.score);max=s1;if(max.score<s2.score)max=s2;if(max.score<s3.score)max=s3;printf("Thestudentwithmaxscoreis:\n");printf("%d%10s%4d\n",max.no,,max.score);}
第2種方法:使用指針變量,找出其中成績(jī)最高的學(xué)生。程序的前面不動(dòng),只是定義指針變量p代替上面的max,程序修改如下:8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析structstudents*p;…printf("%d%s%4d\n",s3.no,,s3.score);p=&s1; if(p->score<s2.score)p=&s2;if(p->score<s3.score)p=&s3;printf("Thestudentwithmaxscoreis:\n");printf("%d%10s%4d\n",p->no,p->name,p->score);…8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析分析:在程序中可以看到,對(duì)結(jié)構(gòu)體變量賦值時(shí),必須對(duì)其每一個(gè)分量賦值〔定義時(shí)初始化例外〕。但同結(jié)構(gòu)的結(jié)構(gòu)體變量之間可以整體賦值,這與數(shù)組的操作完全不同。輸出結(jié)構(gòu)體變量時(shí)也只能通過(guò)輸出其中的每一個(gè)成員來(lái)實(shí)現(xiàn),不能整體輸出。對(duì)結(jié)構(gòu)體類(lèi)型數(shù)據(jù)的根本操作,例如求平均值、最大值、最小值、排序等,算法與簡(jiǎn)單型數(shù)據(jù)的算法是一樣的,只是操作時(shí)針對(duì)結(jié)構(gòu)體類(lèi)型數(shù)據(jù)中的某一個(gè)成員而已。針對(duì)上面的例子,請(qǐng)讀者自己完成求三個(gè)學(xué)生平均分的操作,以及完成成績(jī)從高到低輸出的操作。8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析例8.3修改例8.2,輸入100名學(xué)生信息〔信息包括學(xué)號(hào)、姓名和計(jì)算機(jī)成績(jī)〕,然后輸出這100名學(xué)生信息。最后編寫(xiě)一函數(shù),求出其中成績(jī)最高的學(xué)生,通過(guò)函數(shù)調(diào)用輸出此成績(jī)最高的學(xué)生信息。程序如下:#include<stdio.h>structstudents{longno;charname[10];intscore;};#defineN100intfind(structstudentsa[],intn){intp=0,i;for(i=1;i<n;i++)if(a[i].score>a[p].score)p=i;returnp;}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析main(){structstudentss[N],max;for(inti=0;i<N;i++)scanf("%ld%s%d",&s[i].no,s[i].name,&s[i].score);for(i=0;i<N;i++)printf("%10d%10s%4d\n",s[i].no,s[i].name,s[i].score);max=s[find(s,N)];printf("Thestudentwithmaxscoreis:\n");printf("%10d%10s%4d\n",max.no,,max.score);}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析分析:有100個(gè)學(xué)生,自然不能再用100個(gè)變量描述,需設(shè)置結(jié)構(gòu)體數(shù)組完成。結(jié)構(gòu)體數(shù)組作函數(shù)的參數(shù)用法與其他類(lèi)型數(shù)組作函數(shù)參數(shù)一樣。函數(shù)返回值的設(shè)置,可以把成績(jī)最高學(xué)生的結(jié)構(gòu)體整體設(shè)為返回值,也可以只返回他在數(shù)組中的下標(biāo),也可以返回指向他的指針??紤]到整體返回要進(jìn)行相應(yīng)的數(shù)據(jù)復(fù)制,需要較大的系統(tǒng)開(kāi)銷(xiāo),因此選擇返回下標(biāo)。函數(shù)的參數(shù)和返回值都可能設(shè)置為結(jié)構(gòu)體類(lèi)型的指針變量,請(qǐng)讀者自己修改完成。8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析例8.4模擬一個(gè)井字棋雙人對(duì)戰(zhàn)游戲。井字棋游戲的棋盤(pán)是一個(gè)2*2的格子,棋子下在交叉點(diǎn)上,交叉點(diǎn)正好是3行3列,最早連成3個(gè)棋子成一線(xiàn)的一方獲勝。程序如右:structposition{intx;inty;};intqipan[3][3]={0};/*棋盤(pán)數(shù)據(jù)結(jié)構(gòu)*/voidprintqipan(intqp[3][3])/*打印棋盤(pán)*/{inti;for(i=0;i<3;i++){if(qp[i][0]==0)printf("+--");elseif(qp[i][0]==1)printf("o--");elseprintf("*--");if(qp[i][1]==0)printf("+--");elseif(qp[i][1]==1)printf("o--");elseprintf("*--");if(qp[i][2]==0)printf("+");elseif(qp[i][2]==1)printf("o");elseprintf("*");printf("\n");}}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析intcheck(structposition*play,inti)/*檢測(cè)有無(wú)3個(gè)棋子連成一線(xiàn)*/{intk;intx=play[i].x;inty=play[i].y;intqizi=qipan[x][y];for(k=0;k<=2;k++)*/檢查所在行是否都是同一棋子*/if(qipan[x][k]!=qizi)break;if(k>2)return1;for(k=0;k<=2;k++)*/檢查所在列是否都是同一棋子*/if(qipan[k][y]!=qizi)break;if(k>2)return1;for(k=0;k<=2;k++)*/檢查所在對(duì)角線(xiàn)是否都是同一棋子*/if(qipan[k][k]!=qizi)break;if(k>2)return1;for(k=0;k<=2;k++)*/檢查所在反對(duì)角線(xiàn)是否都是同一棋子*/if(qipan[k][2-k]!=qizi)break;if(k>2)return1;return0;}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析if(check(play1,i)){printf("1號(hào)選手勝利了");return;}if(num==9)break;/*最多只有9個(gè)位置*/do{printf(“選手2輸入下子的位置:");scanf("%d,%d",&t_x,&t_y);}while(qipan[t_x][t_y]!=0);play2[i].x=t_x;play2[i].y=t_y;qipang[t_x][t_y]=2;num+=1;printqipan(qipan);if(check(play2,i)){printf("2號(hào)選手勝利了");return;}i++;}printf("兩人都失敗了");}main(){inti,num=0,t_x,t_y;structpositionplay1[5],play2[5];/*每個(gè)選手最多下5次*/printqipan(qipan);i=1;while(num<9){do{printf("選手1輸入下子的位置:");scanf("%d,%d",&t_x,&t_y);}while(qipan[t_x][t_y]!=0);play1[i].x=t_x;play1[i].y=t_y;qipan[t_x][t_y]=1;num+=1;printqipan(qipan);8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于結(jié)構(gòu)體知識(shí)編程技巧分析〔1〕棋盤(pán)的模擬。因?yàn)槠灞P(pán)上的交叉點(diǎn)正好是3行3列,因此用一個(gè)3行3列的二維數(shù)組即可。數(shù)組元素初始值為0,表示未有棋子落下;值為1表示落下的是1號(hào)選手棋子,值為2表示落下的是2號(hào)選手的棋子?!?〕是否連成一線(xiàn)的檢測(cè)。對(duì)剛落下的棋子檢查所在行是否都是同一個(gè)選手的棋子;同樣再檢測(cè)所在列是否都是同一選手的棋子;同樣的方法再檢測(cè)對(duì)角線(xiàn)和反對(duì)角線(xiàn)?!?〕對(duì)棋子位置的描述。用一個(gè)結(jié)構(gòu)體,把棋子所在的行號(hào)和列號(hào)組合在一起。程序中對(duì)連成一線(xiàn)的檢測(cè)是從棋盤(pán)的角度出發(fā),檢測(cè)有沒(méi)有相同值的行、列、對(duì)角線(xiàn),我們也可從選手已下的棋子,即play1、play2數(shù)組出發(fā),檢測(cè)是否有3個(gè)的同值的行號(hào)分量或列號(hào)分量。程序請(qǐng)讀者編寫(xiě)。8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析8.3.2關(guān)于共用體和枚舉類(lèi)型知識(shí)編程技巧分析例8.6有一個(gè)教師與學(xué)生通用的表格,教師有姓名、年齡、類(lèi)型、教研室四項(xiàng)數(shù)據(jù)。學(xué)生有姓名、年齡、類(lèi)型、班級(jí)四項(xiàng)數(shù)據(jù)。輸入所有教師和學(xué)生的數(shù)據(jù),再以表格形式輸出。程序如下:#include<stdio.h>#defineN100/*設(shè)教師和學(xué)生共有N個(gè)*/unionc_t{intclassno;/*學(xué)生班級(jí)號(hào)*/charoffice[10];/*教師教研室名*/};structStu_Tea
{charname[10];/*姓名*/intage;/*年齡*/inttype;/*類(lèi)型*/unionc_tdepart;/*教研室名或班級(jí)號(hào)*/};8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于共用體和枚舉類(lèi)型知識(shí)編程技巧分析voidmain(){structStu_Teabody[N];inti,k;for(i=0;i<N;i++)/*輸入學(xué)生或教師信息*/{printf("輸入姓名、年齡\n");scanf("%s%d",body[i].name,&body[i].age);printf("假設(shè)此人是教師,類(lèi)型請(qǐng)輸入1;假設(shè)此人是學(xué)生,類(lèi)型請(qǐng)輸入0。\n");scanf("%d",&body[i].type);if(body[i].type==1)/*此人是教師,輸入教研室名*/{printf("輸入教研室名\n");scanf("%s",body[i].depart.office);}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于共用體和枚舉類(lèi)型知識(shí)編程技巧分析if(body[i].type==0)/*此人是學(xué)生,輸入班級(jí)號(hào)*/{printf("輸入班級(jí)號(hào)\n");scanf("%d",&body[i].depart.classno);}}printf("姓名、年齡、教研室或班級(jí)\n");/*顯示學(xué)生、教師信息*/for(i=0;i<N;i++){if(body[i].type==0)printf("%s\t%4d%4d\n",body[i].name,body[i].age,body[i].depart.classno);if(body[i].type==1)printf("%s\t%4d%s\n",body[i].name,body[i].age,body[i].depart.office);}}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于共用體和枚舉類(lèi)型知識(shí)編程技巧分析分析:以上程序中,結(jié)構(gòu)體中的一個(gè)成員depart的類(lèi)型是共用體,對(duì)于類(lèi)型是學(xué)生或教師,可以選取不同的共用體成員。變量的引用是通過(guò)成員引用符“.〞實(shí)現(xiàn)的,同結(jié)體變量的引用一樣,也可以通過(guò)共用體指針變量引用,同樣,需要使用“->〞運(yùn)算符實(shí)現(xiàn)。在計(jì)算機(jī)硬件編程中,尤其是單片機(jī)的C語(yǔ)言編程中,當(dāng)需要訪問(wèn)存放器時(shí),經(jīng)常會(huì)通過(guò)共用體類(lèi)型變量來(lái)定義存放器,進(jìn)一步的學(xué)習(xí)請(qǐng)讀者查閱相關(guān)資料。8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于共用體和枚舉類(lèi)型知識(shí)編程技巧分析例8.7口袋中有紅、黃、藍(lán)、白、黑5種顏色的球假設(shè)干個(gè)。每次從口袋中先后取出3個(gè)球,問(wèn)得到3種不同色的球的可能取法,輸出每種可能取法排列的情況。程序如下:#include<stdio.h>main(){enumcolor{red,yellow,blue,white,black};/*聲明枚舉類(lèi)型color*/enumcolori,j,k,pri;intn=0,loop;/*定義枚舉變量*/for(i=red;i<=black;i++)/*逐個(gè)檢查是否符合條件*/for(j=red;j<=black;j++)if(i!=j){for(k=red;k<=black;k++)8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于共用體和枚舉類(lèi)型知識(shí)編程技巧分析
if((k!=i)&&(k!=j)){n=n+1;printf("%-4d",n);for(loop=1;loop<=3;loop++){switch(loop) {case1:pri=i;break;case2:pri=j;break;case3:pri=k;break;default:break;}switch(pri){casered:printf("%-10s","red");break;caseyellow:printf("%-10s","yellow");break;caseblue:printf("%-10s","blue");break;casewhite:printf("%-10s","white");break;caseblack:printf("%-10s","black");break;default:break;}}printf("\n");}}printf("\ntotal:%5d\n",n);}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析8.3.2關(guān)于共用體和枚舉類(lèi)型知識(shí)編程技巧分析
分析:每個(gè)球只能是5種色之一,而且要判斷各球是否同色,所以用枚舉類(lèi)型變量處理。程序采用窮舉法,設(shè)取出的球?yàn)椋椤ⅲ?、k。根?jù)題意,i、j、k分別是5種色球之一,并要求i≠j≠k。通過(guò)三重循環(huán)把每一種組合都試一下,看哪一組符合條件。8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析8.3.3關(guān)于鏈表知識(shí)編程技巧分析例8.8從鍵盤(pán)輸入假設(shè)干個(gè)非零整數(shù)作為結(jié)點(diǎn)的數(shù)據(jù)元素,創(chuàng)立單向鏈表。程序如下:#include"stdio.h"#include"stdlib.h"#include"malloc.h"structLnode{intdata;structLnode*next;}*p,*q,*head;/*p為跟蹤表尾的指針,q為指向新結(jié)點(diǎn)的指針,head是指向頭結(jié)點(diǎn)的指針*/8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析main(){inttemp;head=(structLnode*)malloc(sizeof(structLnode));if(head==NULL){printf("memoryallocatingerror!");exit(0);}head->next=NULL;p=head;printf("inputainteger:");scanf("%d",&temp);while(temp!=0){q=(structLnode*)malloc(sizeof(structLnode));if(q==NULL){printf("memoryallocatingerror!");exit(0);}q->data=temp;q->next=NULL;p->next=q;p=q;printf("inputainteger:");scanf("%d",&temp);}}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析8.3.3關(guān)于鏈表知識(shí)編程技巧分析分析:〔1〕為了簡(jiǎn)化鏈表操作中對(duì)表中有結(jié)點(diǎn)和無(wú)結(jié)點(diǎn)的情況處理,一般會(huì)在鏈表中增加一個(gè)結(jié)點(diǎn),作為鏈表的第一個(gè)結(jié)點(diǎn),但該結(jié)點(diǎn)不存放數(shù)據(jù)元素,特稱(chēng)之為頭結(jié)點(diǎn)。頭結(jié)點(diǎn)的指針成員存放下一個(gè)數(shù)據(jù)元素結(jié)點(diǎn)的首地址?!?〕首先建立一個(gè)有一個(gè)頭結(jié)點(diǎn)的單向鏈表,采用每次在鏈表的尾部增加一個(gè)結(jié)點(diǎn)的方式,將數(shù)據(jù)元素結(jié)點(diǎn)鏈接起來(lái)。由于新結(jié)點(diǎn)是添加在單向鏈表的尾部,故需要設(shè)置一個(gè)指向表尾的指針,且每添加一個(gè)新結(jié)點(diǎn)就要更新此指針。8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析上述程序建立起來(lái)的單鏈表數(shù)據(jù)的順序正好與輸入的順序一致。如果對(duì)數(shù)據(jù)的順序不作要求,那么可以把新結(jié)點(diǎn)添加在鏈表的頭部,這樣就不需要跟蹤表尾指針,新建鏈表的效率更高。程序如下:#include"stdio.h"#include"stdlib.h"#include"malloc.h"structLnode{intdata;structLnode*next;}*q,*head;main(){inttemp;head=(structLnode*)malloc(sizeof(structLnode));8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析if(head==NULL){printf("memoryallocatingerror!");exit(0);}head->next=NULL;printf("inputainteger:");scanf("%d",&temp);while(temp!=0){q=(structLnode*)malloc(sizeof(structLnode));if(q==NULL){printf("memoryallocatingerror!");exit(0);}q->data=temp;q->next=head->next;head->next=q;printf("inputainteger:");scanf("%d",&temp);}}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析例8.9單向鏈表有10個(gè)結(jié)點(diǎn),各結(jié)點(diǎn)的數(shù)據(jù)成員data的值分別是1、3、5、7、9、11、13、15、17、19。將一個(gè)新結(jié)點(diǎn)插入到該單向鏈表的第i個(gè)結(jié)點(diǎn)位置上〔頭結(jié)點(diǎn)之后的第一個(gè)元素序號(hào)為1〕。程序如下:#include"stdio.h"#include"malloc.h"structnode{intdata;structnode*next;};8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析structnode*insert(structnode*head,inti,intnewdata){structnode*q,*p;intj;if(i<0){printf("插入位置不存在");returnhead;}q=(structnode*)malloc(sizeof(structnode));q->data=newdata;p=head->next;j=1;while(p!=NULL&&j<i-1){j++;p=p->next;}if(p!=NULL){q->next=p->next;p->next=q;}returnhead;}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析main(){structnode*head,*newnode,*rear;inti,x;head=(structnode*)malloc(sizeof(structnode));head->next=NULL;
rear=head;for(i=1;i<=10;i++){newnode=(structnode*)malloc(sizeof(structnode));newnode->data=2*i-1;/*原鏈表的數(shù)據(jù)為1,3,5,7……*/newnode->next=NULL;
rear->next=newnode;
rear=newnode;}printf("請(qǐng)輸入新結(jié)點(diǎn)數(shù)據(jù)及插入的位置");scanf("%d%d",&x,&i);head=insert(head,i,x);printf("插入后的鏈表數(shù)據(jù)為:\n");for(structnode*p=head->next;p!=NULL;p=p->next)printf("%d-->",p->data);}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析分析:在p指針指向的結(jié)點(diǎn)插入之后,設(shè)新結(jié)點(diǎn)由指針q指向,那么插入的過(guò)程為:q->next=p->next;p->next=q;這種方法的關(guān)鍵之處是先要找到p的位置。由于新結(jié)點(diǎn)是插入在第i個(gè)位置上,因此p應(yīng)該是指向第i-1個(gè)結(jié)點(diǎn)的指針。上述算法需要先對(duì)鏈表進(jìn)行一次遍歷,如果問(wèn)題中已告訴插入的位置為p指向的位置,能否不進(jìn)行遍歷,直接把新結(jié)點(diǎn)插入到p指針指向的位置呢?可以采用如下方法,將新結(jié)點(diǎn)插入在p指針指向的結(jié)點(diǎn)之前。首先分配一個(gè)結(jié)點(diǎn)q,將q插入在p后,接下來(lái)將p結(jié)點(diǎn)與q結(jié)點(diǎn)的數(shù)據(jù)域的值作一下交換。這種方法算法就不需要遍歷鏈表了,效率高于前一方法。程序如下:8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析#include"stdio.h"#include"malloc.h"structnode{intdata;structnode*next;};voidinsert2(structnode*p,intnewdata){structnode*q;intt;q=(structnode*)malloc(sizeof(structnode));q->data=newdata;q->next=p->next;p->next=q;/*將q插入在p的后面*/t=p->data;p->data=q->data;q->data=t;/*交換p和q的data值*/return;}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析main(){structnode*head,*newnode,*rear;inti,x;head=(structnode*)malloc(sizeof(structnode));head->next=NULL;rear=head;for(i=1;i<=10;i++){newnode=(structnode*)malloc(sizeof(structnode));newnode->data=2*i-1;/*原鏈表為有序的數(shù)據(jù)為1,3,5,7……*/newnode->next=NULL;rear->next=newnode;rear=newnode;}printf("請(qǐng)輸入新結(jié)點(diǎn)數(shù)據(jù)");scanf("%d",&x);for(structnode*p=head->next;p->data<x;p=p->next);insert2(p,x);printf("插入后的鏈表數(shù)據(jù)為:\n");for(p=head->next;p!=NULL;p=p->next)printf("%d-->",p->data);}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析例8.10編寫(xiě)函數(shù),在單向鏈表中刪除指定結(jié)點(diǎn)。給定一個(gè)特定值,假設(shè)單鏈表中某個(gè)數(shù)據(jù)結(jié)點(diǎn)的值與此特定值相同,那么刪除該結(jié)點(diǎn);假設(shè)不存在,那么給出提示信息。程序如下:#include"stdio.h"#include"stdlib.h"#include"malloc.h"structLNode{intnum;structLNode*next;};8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析structLNode*del(structLNode*head,longnum){structLNode*p,*q;if(head==NULL){printf("\nlistnull!\n");returnhead;}p=head;while(num!=p->num&&p->next!=NULL){q=p;p=p->next;}if(num==p->num){if(p==head)head=p->next;else{q->next=p->next;free(p);}printf("delete:%ld\n",num);}elseprintf("%ldnotbeenfound!\n",num);return(head);}關(guān)于鏈表知識(shí)編程技巧分析例8.10分析:〔1〕要?jiǎng)h除特定值結(jié)點(diǎn),需要先遍歷單鏈表,找到待刪除的位置?!?〕刪除指針變量p指向的結(jié)點(diǎn),首先需要先得到p指向的結(jié)點(diǎn)的前面一個(gè)結(jié)點(diǎn)。因此,需要用指針變量q指向p所指向的結(jié)點(diǎn)的前面一個(gè)結(jié)點(diǎn)?!?〕刪除結(jié)點(diǎn)不僅要修改指針的指向,還要用free函數(shù)釋放被刪除結(jié)點(diǎn)所占據(jù)的內(nèi)存。8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析例8.11對(duì)于單向鏈表,設(shè)計(jì)一個(gè)函數(shù),從尾到頭反過(guò)來(lái)輸出每個(gè)結(jié)點(diǎn)的值,要求不破壞單鏈表。程序如下:voidprint_node(structnode*head){if(head==NULL)return;else{print_node(head->next);printf("%d",head->data);}}分析:〔1〕如果允許破壞此單向鏈表,那么可以先把此單向鏈表倒置,再依次輸出所有結(jié)點(diǎn)。這種方法簡(jiǎn)單明了,輸出每個(gè)結(jié)點(diǎn)容易實(shí)現(xiàn)。〔2〕本程序用遞歸程序?qū)崿F(xiàn),利用遞歸算法可以使得輸出倒序。8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析〔3〕用上述的遞歸程序需要屢次的函數(shù)調(diào)用,效率低下,可以考慮直接用堆棧的方法實(shí)現(xiàn)。先順序依次訪問(wèn)單向鏈表,把讀到的數(shù)據(jù)壓入到堆棧中,全部讀完后再?gòu)亩褩V袕棾鼍涂梢苑催^(guò)來(lái)輸出每個(gè)結(jié)點(diǎn)的值了??紤]到壓棧、出棧的開(kāi)銷(xiāo),可以用一個(gè)數(shù)組代替堆棧。程序如下:structnode{intdata;structnode*next;};voidprint_node(structnode*head){structnode*p=head->next;/*head指向的是頭結(jié)點(diǎn)。p指向第一個(gè)元素。*/intstack[100];/*模擬堆棧,假定結(jié)點(diǎn)元素類(lèi)型為整型,不超過(guò)100個(gè)結(jié)點(diǎn)*/inti=0;while(p!=NULL){stack[++i]=p->data;p=p->next;}while(i>0)printf(“%d,〞,stack[i--]);}8.3結(jié)構(gòu)體、共用體和枚舉類(lèi)型以及鏈表編程技巧分析關(guān)于鏈表知識(shí)編程技巧分析例8.12編寫(xiě)函數(shù),將兩個(gè)有序的單向鏈表合并,要求在原有的結(jié)點(diǎn)根底上修改指針的指向,不產(chǎn)生新的結(jié)點(diǎn)。程序如下:structNode{intnum;structNode*next;};structNode*MergeList(structNode*head1,structNode*head2)/*按升序合并*/{structNode*head,*temp;if(head1==NULL)returnhead2;if(head2==NULL)returnhead1;if(head1->num<=head2->num){head=head1;head1=head1->next;}else
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度教育咨詢(xún)服務(wù)辦學(xué)許可證轉(zhuǎn)讓及服務(wù)協(xié)議3篇
- 2025年臨時(shí)用工合作協(xié)議確保二零二五年度客戶(hù)服務(wù)品質(zhì)3篇
- 2025年二零二五企業(yè)倉(cāng)儲(chǔ)物流場(chǎng)地租賃服務(wù)合同3篇
- 2025年度年度影視行業(yè)兼職演員聘用協(xié)議2篇
- 二零二五年度銷(xiāo)售團(tuán)隊(duì)保密責(zé)任協(xié)議
- 2025年度新型城鎮(zhèn)化工程款結(jié)算與進(jìn)度管理協(xié)議3篇
- 2025年度全新競(jìng)業(yè)協(xié)議解除后一個(gè)月競(jìng)業(yè)限制合同3篇
- 二零二五年度新能源汽車(chē)購(gòu)買(mǎi)協(xié)議3篇
- 2025年度公司與個(gè)人合作代收代付電商業(yè)務(wù)合同模板3篇
- 二零二五年度農(nóng)產(chǎn)品電商平臺(tái)用戶(hù)行為分析合作協(xié)議3篇
- 數(shù)學(xué)-湖南省天一大聯(lián)考暨郴州市2025屆高考高三第二次教學(xué)質(zhì)量檢測(cè)(郴州二檢懷化統(tǒng)考)試題和答案
- 2024-2025學(xué)年人教版生物學(xué)八年級(jí)上冊(cè)期末復(fù)習(xí)測(cè)試題(含答案)
- 施工現(xiàn)場(chǎng)環(huán)保要求措施
- 重癥患者的營(yíng)養(yǎng)支持
- 瓷磚店銷(xiāo)售薪酬方案
- 小學(xué)體育課件教學(xué)
- 2024年事業(yè)單位招聘考試計(jì)算機(jī)基礎(chǔ)知識(shí)復(fù)習(xí)題庫(kù)及答案(共600題)
- 西京學(xué)院《機(jī)械制造技術(shù)基礎(chǔ)》2022-2023學(xué)年第一學(xué)期期末試卷
- 我和我的祖國(guó)拼音版
- 2023年生態(tài)環(huán)境綜合行政執(zhí)法考試參考題庫(kù)(400題)
- 湖南某水庫(kù)防汛應(yīng)急預(yù)案
評(píng)論
0/150
提交評(píng)論