第09章C語言高級程序設(shè)計ppt課件_第1頁
第09章C語言高級程序設(shè)計ppt課件_第2頁
第09章C語言高級程序設(shè)計ppt課件_第3頁
第09章C語言高級程序設(shè)計ppt課件_第4頁
第09章C語言高級程序設(shè)計ppt課件_第5頁
已閱讀5頁,還剩78頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、C言語程序設(shè)計湖南工學(xué)院第第9 9章章 C C言語高級程序設(shè)計言語高級程序設(shè)計 9.1 9.1 編譯預(yù)處置命令編譯預(yù)處置命令 9.2 9.2 位運算位運算 9.3 9.3 構(gòu)造體高級運用鏈表構(gòu)造體高級運用鏈表 本章小結(jié)本章小結(jié)9.1 9.1 編譯預(yù)處置命令編譯預(yù)處置命令 ANSI C 規(guī)范規(guī)定可以在C源程序中參與一些“預(yù)處置命令,以改良程序環(huán)境,提高編程效率。C程序中編譯預(yù)處置語句的作用不是實現(xiàn)程序的功能,它們是發(fā)送給編譯系統(tǒng)的信息。也就是說,對于預(yù)處置命令,必需在程序編譯之前,先對這些特殊命令進展“預(yù)處置。經(jīng)過預(yù)處置后程序不再包含預(yù)處置命令了。 C言語提供的預(yù)處置功能主要有宏定義、文件包含及

2、條件編譯三種。 分別用宏定義命令,文件包含命令,條件編譯命令來實現(xiàn)。為了與普通C語句相區(qū)別,這些命令以符號“#開頭。 9.1.1 9.1.1 宏宏 宏定義功能是定義符號常量和常參數(shù)的宏,宏定義編譯預(yù)處置語句的格式如下 : #define 字符串1 字符串2它把字符串1定義為字符串2,字符串1稱為字符串2的宏定義,例如,下面是符號常量的宏定義: #define ON 1 #define OFF 0 它把符號常量ON定義為1,OFF定義為0。符號常量經(jīng)過宏定義后,就可以在程序中作為常量運用。例如: if(a=ON)printf(“Switch is ONn);else if(a=OFF)print

3、f(“Switch is OFFn); 在系統(tǒng)執(zhí)行編譯預(yù)處置過程時,將把程序中出現(xiàn)的字符串1一概用字符串2置換,就是說程序中的符號常量用定義它們的常量置換,然后再對置換處置后的源文件進展編譯。如上面程序段經(jīng)編譯預(yù)處置后成為以下方式: if(a=1)printf(“Switch is ONn);else if(a=2)printf(“Switch is OFFn); 在宏定義語句中,可以運用曾經(jīng)定義過的符號常量定義新的符號常理。例如: #define WID 40 #define LEN WID+20 其中第二個宏定義中運用了第一個宏定義的符號常量WID。在執(zhí)行編譯預(yù)處置時,程序中出現(xiàn)的一切符號

4、常量WID都將被40置換,一切的符號常量LEN不帶參數(shù)的宏定義:用一個指定的標(biāo)識符(即名字)來代表一個字符串。普通方式:#define 標(biāo)識符 字符串例:#define PI 3.14159闡明:1宏名普通習(xí)慣用大寫字母表示。2運用宏名替代一個字符串,可以減少程序中反復(fù)書寫某些字符串的任務(wù)量。3宏定義是用宏名替代一個字符串,也就是作簡單的置換,不作正確性檢查。4宏定義不是C語句,不用在行末加分號. #define PI 3.14159; area=PI*r*r; 展開: area=3.14159;*r*r; 出現(xiàn)語法錯誤5#define命令出如今程序中函數(shù)的外面,宏名的有效范圍為定義命令之后到

5、根源文件終了。6可以用#undef命令終止宏定義的作用域。 格式:#undef 宏名7在進展宏定義時,可以援用已定義的宏名,可以層層置換。 #define R 3.0 #define PI 3.14159 #define L 2*PI*R #define S PI*R*R main( ) printf(“L=%fnS=%fn,L,S); 8對程序中用雙括號括起來的字符串內(nèi)的字符,即使與宏名一樣,也不進展置換。9宏定義是專門用于預(yù)處置命令,只作字符交換。帶參數(shù)的宏定義:不是進展簡單的字符串交換,還要進展對數(shù)交換。普通方式: #define 宏名(參數(shù)表) 字符串例:#define S(a,b)

6、a*b area=S(3,2) #define PI 3.14159 #define S(r) PI*r*r main() float a ,area; a=3.6; area=S(a); printf(“r=%fnarea=%fn,a,area);闡明:1對帶參數(shù)的宏的展開只是將語句中的宏名后面括號內(nèi)的實參字符串替代#define命令行中的形參。 area=S(a+b) 把實參a+b替代PI*r*r中的形參r,成為: area=PI*a+b*a+b那么 #define S(r) PI*( r)*( r) 都將被40+20置換。例如,程序中的以下語句: area=LEN*WID;在執(zhí)行編譯預(yù)處

7、置時,該語句將被置換成: area=(40+20)*40; 經(jīng)運算后變量area的值是2400。從上面的置換過程可以看到,LEN定義時包圍WID+20的圓括號是不可短少的,假設(shè)上面的宏定義時不運用圓括號: #define LEN WID+20那么上面的area賦值表達式在編譯預(yù)處置后成為: area=40+20*40; 這時變量area的計算結(jié)果值是840,它并不是預(yù)定的計算結(jié)果。因此,在進展宏定義時,為了保證宏定義被置換后仍堅持正確的運算順序,經(jīng)常在定義式中運用必要的圓括號包圍定義的式子。 在C言語程序中,宏定義語句除了定義符號常量外,還經(jīng)常用于定義帶參數(shù)的宏,帶參數(shù)的宏是在定義的宏定義中可

8、以帶有假設(shè)干參數(shù)。例如: #define MULT2X X*X 其中,MULT2X稱為帶參數(shù)的宏,X是它的方式參數(shù)。該宏定義把MULT2X定義為X*X。在此定義后,MULT2X就可以用在程序中替代定義它的運算表達式X*X。它的方式參數(shù)的運用特性類似于函數(shù)的方式參數(shù)。在程序中需求計算某個數(shù)的平方值時,可以運用這個已定義 的宏,例如:a=10;c=MULT2(a); 在進展編譯預(yù)處置時,帶參數(shù)的宏用它的定義置換,其中的方式參數(shù)用實踐運用的實踐參數(shù)置換。因此,上面的賦值表達式置換后的方式是:c=a*a; 其中定義式中的方式參數(shù)X被實踐參數(shù)a置換,該運算表達式的結(jié)果是100。當(dāng)程序中需求計算某兩個變量

9、和的平方時,假設(shè)運用上面定義的帶參數(shù)的宏的話,如下所示:w=6;v=4;c=MULT2(w+v); 進展編譯預(yù)處置后,上面的賦值表達式置換后的方式是: c=w+v*w+v; 它的運算順序與預(yù)定的順序完全不同,計算結(jié)果是34。假設(shè)上面的宏定義改為以下方式: #define MULT2X X*X上面的賦值表達式置換后就成為: c=w+v*w+v; 它的運算結(jié)果就正確了。這里又一次看到在定義式中運用必要圓括號的重要性。 【例9.1】程序中的宏定義計算球的體積 程序如L9-1.c該程序在編譯預(yù)處置中,計算球體積的表達式語句:v=4*PI*MULT3(r)/3;其中的兩個宏定義PI和MULT3將分別由定

10、義它們的常量和表達式進展置換,實踐上參與編譯的語句如下所示: v=4*3.1415926*(r)*(r)*(r)/3; 在程序設(shè)計時,經(jīng)常把那些反復(fù)運用的運算表達式定義不帶參數(shù)的宏,這樣一方面使程序更加簡約,另一方面可以使運算的意義更加明顯。下面再給出幾個帶參數(shù)宏的例子,它們都是運用三項條件表達式定義的。 #define min(x,y) (x=0)?x:-x)求x的絕對值。#define sign(x) (x0)?1:(x1)? 1:0) 判別x的符號。 上面給出的宏定義中,在定義式的運算表達式里都是單純的方式。在實踐運用時,應(yīng)該根據(jù)需求加上保證運算順序的圓括號。9.1.2 9.1.2 文件

11、包含文件包含 “文件包含處置 所謂“文件包含處置是指一個源文件可以將另外一個源文件的全部內(nèi)容包含進來,即將另外的文件包含到本文件之中。C言語提供了#inctude命令用來實現(xiàn)“文件包含的操作。其普通方式為 # include “文件名或 #include 留意:1一個include命令只能指定一個被包含文件,假設(shè)要包含幾個文件,要用幾個include命令。2假設(shè)文件1包含文件2,而文件2中要用到文件3的內(nèi)容,那么可在文件1中用兩個inctude命令分別包含文件2和文件3,而且文件3應(yīng)出如今文件2之前,即在filel.C中定義: #include “file3.h #include “file2

12、.h 這樣,fite1和file2都可以用file3的內(nèi)容。在file2中不用再用#include 了。3在一個被包含文件中又可以包含另一個被包含文件,即文件包含是可以嵌套的?!纠?.2】文件put.h運用TYPE命令顯示的內(nèi)容如put.h代碼,它包含有各種輸出格式的帶參數(shù)宏的定義: 程序如L9-2.c【例9.3】 有如下兩個源文件: filel.h L9-3.c9.1.3 條件編譯條件編譯 為理處理程序的可移植性問題,C言語提供了條件編譯命令,它能運用一個源程序在不同的編譯環(huán)境下生成不同的目的文件,條件編譯命令有以下幾種: 1# ifdef 標(biāo)識符 程序段1 # else 程序段2 # en

13、dif 其功能是用來測試測試一個標(biāo)識符宏名能否被定義,假設(shè)標(biāo)識符已被定義,那么在程序編譯階段只編譯程序段1,否那么編譯程序段2。該命令方式的簡化方式是沒有#else部分,這時,假設(shè)標(biāo)識符未定義,那么此命令中沒有程序段被編譯。 2# ifndef 標(biāo)識符 程序段1 # else 程序段2 # endif其功能是用來測試測試一個標(biāo)識符宏名能否未曾被定義,假設(shè)標(biāo)識符未被定義,那么編譯程序段1,否那么編譯程序段2。該命令方式的簡化方式是沒有#else部分,這時,假設(shè)標(biāo)識符已定義,那么此命令中沒有程序段被編譯。3#if 表達式 程序段1 #else 程序段2 #endif 它的作用是當(dāng)指定的表達式為真時

14、就編譯程序段1,否那么編譯程序段2。其中的表達式必需是整型常量表達式不包含sizeof運算符、強迫類型轉(zhuǎn)換和枚舉常量。該命令方式的簡化方式是沒有#else部分,這時,假設(shè)表達式為“假,那么此命令中沒有程序段被編譯。 4#if 表達式1 程序段1 #elif 表達式2 程序段2 #elif 表達式3 程序段3 #else 程序段n #endif 這里的#elif其含義是“else if,該命令的功能是,假設(shè)常量表達式1的值為“真,那么編譯程序段1,否那么假設(shè)常量表達式2的值為“真,那么編譯程序段2,假設(shè)常量表達式的值都為“假,那么編譯程序段n。也可以沒有#else部分,這時,假設(shè)一切表達式的值都

15、為“假,那么此命令中沒有程序段被編譯。5 #if defined(宏名) 程序段1 #else 程序段2 #endif 該命令等價于#ifdef 標(biāo)識符,但該命令可以判別多個宏名的定義情況,而#ifdef命令只能判別一個宏名的定義情況。! Defined(宏名)的作用是當(dāng)宏名未定義時其值為真,因此#if !defined(宏名)等價于#ifndef 標(biāo)識符。 例如,在alloc.h文件中,可以看到以下關(guān)于NULL的定義,其目的是適宜不同編譯方式的兼容性。#ifndef NULL#if defined(_TINY_)|defined(_SMALL_)|defined(_MEDIUM_)#defi

16、ne NULL 0#else#define NULL 0L#endif#endif【例9.4】輸入一個口令,根據(jù)需求設(shè)置條件編譯,使之在調(diào)試程序時,按原碼輸出;在運用時輸出“*號。#define DEBUGvoid main(viod)char pass80;int=-1;printf(“n Pleasa Input Password:);do i+;passi=getch();#ifdef DEBUGputchar(passi);#elseputchar(*);#endifwhile(passi!=n); 9.2 9.2 位運算位運算 所謂位運算,是指對一個數(shù)據(jù)的某些二進制位進展的運算。每個

17、二進制位只能存放1位二進制數(shù)“0或者“1。通常把組成一個數(shù)據(jù)的最右邊的二進制位稱作第0位,從右以此稱為第1位,第二位,最左邊一位稱作最高位,如圖91所示。 9.2.1 9.2.1 位運算和位運算符位運算和位運算符 C言語提供6種運算符,如表9-1所示。闡明: 反運算符“是單目運算符,其他是雙目運算符,即要求兩側(cè)各有一個運算量。 位運算的運算對象只能是整型或字符型數(shù)據(jù),而不能是實型數(shù)據(jù)。 9.2.2 9.2.2 位運算符的運用位運算符的運用 1 按位取反運算符“ 按位取反運算為單目運算,它將運算對象的各位取反,即將1變0,0變1。例如O24是對八進制數(shù)24即二進制數(shù)00010100按位求反:00

18、010100 11101011運算結(jié)果為八進制數(shù)353。2 按位與運算符“& “按位與是指兩個運算對象按對應(yīng)二進制位進展“邏輯與運算,即當(dāng)且僅當(dāng)參與運算的兩個對象的對應(yīng)二進制都為1時,結(jié)果的對應(yīng)二進制位為1,否那么為0。即 0&0=0;0&1=0;1&0=0;1&1=1;例如:設(shè)int x=3,y=5; 由于x,y是整型,占兩個字節(jié),對應(yīng)的二進制方式分別為0000000000000011和0000000000000101,所以x = 0000000000000011y = 0000000000000101 x&y = 00000000000000

19、01 因此,3&5的值值等于1。假設(shè)參與&運算的是負(fù)數(shù)如-3& -5,那么以補碼方式表示為二進制數(shù),然后按位進展“與運算?!鞍次慌c運算的運用主要為:位清零、測試指定位的值和獲取指定位的值。(1)位清零 假設(shè)想將一個數(shù)據(jù)中的某些位清零,根據(jù)“按位與運算的含義,只需求鼗這些位與0進展“按位與運算即可。例95 設(shè)有一個字符型變量8位二進制位,把它的低4位清0。分析:欲使x的低4位為0,只需將x的低4位與0進展“按位與即可。即x=x&0 xf0。運算過程如下:x= * * * * * * * * & 1 1 1 1 0 0 0 0 * * * * 0 0 0 0

20、 其中“*是1或0。(2)測試指定位的值 要想判別某一指定位的值是1還是0,只需將這一位與1進展“按位與運算,然后判別結(jié)果能否為0即可。例96 設(shè)x是一個字符型變量8位二進制位,判別x的最低位能否為0。分析:想要判別x的最低位是0還是1,可以進展如下運算: if(x&0 x01)!=0)那么x的最低位是1;或者 if(x&0 x0 x)=0)那么x的最低位是0;由于:x = * * * * * * * * & 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 * 所以假設(shè)x最低位為1,那么表達式結(jié)果為1;假設(shè)最低位為0,那么表達式結(jié)果為0。留意:“按位與運算&

21、amp;的優(yōu)先級低于關(guān)系運算符!=和=,所以表達式x&0 x01的圓括號不能省略。(3) 獲取指定的值要想獲得某些位的值只需將這些位與1“按位與運算,而將其他位清0即可。例97 設(shè)X是unsigned類型的整數(shù)16位二進制數(shù),要想獲取X的低8位,可做運算X&0X00ff。運算過程為:x=* * * * * * * * * * * * * * * *& 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 * * * * * * * *可以看出,結(jié)果只保管了X的低8位。 例98 從鍵盤輸入一個正整數(shù),判別此數(shù)是奇數(shù)還是偶數(shù)。 分析

22、:一個正數(shù)是奇數(shù)還是偶數(shù),只需求判別最低位是1還是0。假設(shè)最低位為0,該數(shù)是偶數(shù);最低位為1,那么是奇數(shù)。 程序如L9-8.c3 按位或運算符“| “按位或運算是指兩個運算對象按對應(yīng)二進制位進展“邏輯或運算,即當(dāng)參與運算的兩個對象的對應(yīng)二進制位有一個“1時,結(jié)果的對應(yīng)二進制位為“1,如下所示: 0|0=0;0|1=1;1|0=1;1|1=1;例如:設(shè)int x=3,y=-5,那么x|y的結(jié)果如下:x= 0000000000000011| 1111111111111011 1111111111111011 “按位或“運算常用于對一個數(shù)據(jù)中的某些位置1。例99 編一程序,從鍵盤輸入一個字符,假設(shè)是

23、大寫字母,那么轉(zhuǎn)換成小寫字母輸出。分析:字符在計算機內(nèi)是以ASC碼表示的,小寫字母的ASC碼值范圍為16進制數(shù)61H7AH,大寫字母的ASC碼值范圍為16進制數(shù)41H5AH,即小寫字母和大寫字母的ASC碼值相差20H。因此要想把大寫字母轉(zhuǎn)換成小寫字母只需把大寫字母的第6位置1即可。如:A的ASC碼為41H,a的ASC碼值為61H。 A=01000001 41H | 00100000 20H a=01100001 (61H) 程序如L9-9.c4 按位異或運算符“ “按位異或運算是指兩個運算對象按對應(yīng)二進制位進展“邏輯異或運算,即當(dāng)參與運算的兩個對象的相應(yīng)二進制位一個為“0,另一個為“1時,結(jié)果

24、的對應(yīng)二進制位為“1,如下所示: 00=0;01=1;10=1;11=0;“按位異或運算的運用;1使數(shù)據(jù)中的某些位求反。由于0和1的異或結(jié)果為1,1和1的“異或結(jié)果為0,所以只需將要求反的位與1進展“異或運算,就可以將該位求反。2將變量清0。任何一個屬于變量本身的“異或結(jié)果都為0。利用“異或運算的這個性質(zhì)可以完成對變量的清0操作。 5 左移運算符“ 左移運算符“的運用方式為: 運算對象 右移運算符“的運用方式為: 運算對象右移位數(shù) 右移運算符將運算對象的每個二進制位同時向右挪動指定的位數(shù),從右邊移出的低位部分被丟棄。對無符號數(shù),左邊空出的高位補0;對有符號數(shù),正數(shù)的高位部分補0,負(fù)數(shù)的高位部分

25、補0還是1和計算機系統(tǒng)有關(guān)。移入0的稱為“邏輯右移,移入1的稱為“算術(shù)右移。 “邏輯右移相當(dāng)于無符號數(shù)除以2,“算術(shù)右移相當(dāng)于有符號數(shù)除以2。例如:a: 1001011111101101a1: 0100101111110110 -邏輯右移a1: 1100101111110110 -算術(shù)右移7 位復(fù)合賦值運算符 類似于算術(shù)運算的復(fù)合運算符,位運算符和賦值運算符也可以構(gòu)成“復(fù)合賦值運算符。如9-2所示。8 位運算的運用1鍵盤掃描碼 鍵盤上除了ASC|碼外,還有非ASC|碼如左移鍵“對應(yīng)的編碼,叫擴展鍵盤碼。我們把擴展鍵盤碼放在高八位,ASC|碼放在低八位所組成的代碼稱為掃描碼。 對于某一特定的掃描

26、碼,假設(shè)其低八位不為零,那么此八位就是相應(yīng)字符的ASC|碼值;假設(shè)低八位是零,那么高八位是擴展鍵盤碼,需求再讀取入第二個字節(jié),根據(jù)它的值來判別它是那一個功能鍵。表9-3給出了單功能鍵和組合功能鍵的鍵值,表中代碼 系指第二個字節(jié)鍵值的十進制數(shù)。例如,“的掃描碼低八位應(yīng)為零,而高八位是0X4B,所以,“鍵的掃描碼為0X4B00;回車鍵也有對應(yīng)的ASC|碼,故其掃描碼的低八位是回車鍵的ASC|碼值0X0D。(2) 測試鍵盤掃描碼 調(diào)用規(guī)范庫函數(shù)bioskey()讀取鍵盤掃描碼,再經(jīng)過位運算分別低八位字符的ASC|碼和高八位的擴展鍵盤碼。留意運用bioskey()函數(shù),應(yīng)在頭部加上#include “

27、bios.h。例910 利用bioskey()函數(shù),測試鍵盤掃描碼,按ESC鍵退出。算法設(shè)計:1利用位的“與運算,提取低8位low=key & 0 x00ff;假設(shè)low不為零,那么此8位就是相應(yīng)字符的ASC|碼值;否那么2利用位的“與和右移“運算,提取高8位的擴展鍵盤碼 hig=(key & 0 xff00)8;程序如L9-10.c闡明:1關(guān)于函數(shù)bioskey() 函數(shù)bioskey()的功能是用于識別用戶按鍵和獲得按鍵值。函數(shù)原型是: int bioskey(int cmd); 在中定義,在運用它時,運用include命令將bios.h文件包含進來。其中參數(shù)cmd可取0或

28、1。當(dāng)cmd=1時,檢測鍵盤能否擊鍵,假設(shè)沒有擊鍵,函數(shù)將前往0,否那么前往非零;當(dāng)cmd=0時,前往從鍵盤輸入的掃描碼。 語句key=bioskey(0);讀取鍵盤輸入的掃描碼,并存儲在變量key中。 9.2.3 位段位段 在計算機中普通以字節(jié)為單位存放數(shù)據(jù),但實踐上有時存儲一個信息不用用一個字節(jié)或多個字節(jié),例如,“真或“假用0或1表示,即只需求1位表示即可。因此,在計算機里經(jīng)常在一個字節(jié)中放幾個信息。 C言語提供兩種方法,操作一個字節(jié)中的一個或幾個二進制位。1 位運算法 如圖9-2所示,假設(shè)a、b、c和d分別占2位、6位、4位和4位,設(shè)data由a、b、c和d組成。假設(shè)想將c的值置為12,

29、用位運算方法,操作如下:將數(shù)x=12左移4位,使1100成為右面的第47位,即:x=4 (0000000011000000)2 將data與0 xff0f進展“與運算,使data的第47位全為0,即: data &= 0 xffof; 3 將data與“124進展“按位或運算,即: data |= (124)或?qū)?步結(jié)合起來,可以表示為: data = data & 0 xff0f | (12str,pstr)!=0&temp-next!=NULL)/ * 假設(shè)節(jié)點的字符串與輸入字符串不同,并且未到鏈表尾* /p=temp;temp=temp-next; / * 跟蹤鏈

30、表的增長,即指針后移* /if(strcmp(temp-str,pstr)=0 ) / *找到字符串* /if(temp=head) / * 表頭節(jié)點* /printf(delete string :%sn,temp-str);head=head-next;free(temp); / *釋放被刪節(jié)點* /elsep-next=temp-next; /表*中節(jié)點*/printf(delete string :%sn,temp-str);free(temp);else printf(nno find string!n);沒/找* 到要刪除的字符串*/return(head); / *前往表頭指針*

31、 / 2. 鏈表的插入首先定義鏈表的構(gòu)造:structint num; /*學(xué)生學(xué)號* /char str20; /*姓名* /struct node *next; ; 在建立的單鏈表中,插入節(jié)點有三種情況,如圖9 - 7所示。 插入的節(jié)點可以在表頭、表中或表尾。假定我們按照以學(xué)號為順序建立鏈表,那么插入的節(jié)點依次與表中節(jié)點相比較,找到插入位置。由于插入的節(jié)點能夠在鏈表的頭,會對鏈表的頭指針呵斥修正,所以定義插入節(jié)點的函數(shù)的前往值定義為前往構(gòu)造體類型的指針。節(jié)點的插入函數(shù)如下:struct node *insert(head,pstr,n) / *插入學(xué)號為n、姓名為p s t r 的節(jié)點*

32、/struct node *head; / *鏈表的頭指針* /char *pstr;int n;struct node *p1,*p2,*p3;p1=(struct node*)malloc(sizeof(struct node)分;配/*一個新節(jié)點*/strcpy(p1-str,pstr) ; / * 寫入節(jié)點的姓名字串* /p1-num=n ; / * 學(xué)號* /p2=head;if (head=NULL) / * 空表* /head=p1; p1-next=NULL;/ *新節(jié)點插入表頭* /else /*非空表* /while(np2-num&p2-next!=NULL)/

33、*輸入的學(xué)號小于節(jié)點的學(xué)號,并且未到表尾* /p3 = p2 ;p2=p2-next; / * 跟蹤鏈表增長* /if (nnum) / *找到插入位置* /if (head=p2) / * 插入位置在表頭* /head=p1;p1-next=p2;else /*插入位置在表中* /p3-next=p1;p1-next=p2;else /*插入位置在表尾* /p2-next=p1;p1-next=NULL;return(head); / * 前往鏈表的頭指針* / 9.3.3 遍歷鏈表遍歷鏈表 由于鏈表是一個動態(tài)的數(shù)據(jù)構(gòu)造,鏈表的各個結(jié)點由指針鏈接在起,訪問鏈表元素時經(jīng)過每個鏈表結(jié)點的指針逐個

34、找到該結(jié)點的下一個結(jié)點,直找到鏈表尾,鏈表的最后一個結(jié)點的指針為空。例如:編歷鏈表函數(shù)。 void outputlist(LINKLIST *head) LINKLIST *currenthead-next; while(current!NULL) printf(%dn,current-info); current=current-next; return ; 9.3.4雙向鏈表雙向鏈表 每個結(jié)點中只包括一個指向下個結(jié)點的指針域,這種鏈表稱為單向鏈表。假設(shè)要在單向鏈表一個指針?biāo)傅漠?dāng)前位置插入一個新結(jié)點,就必需從鏈表頭指針開場逐個遍歷直到當(dāng)前指針?biāo)附Y(jié)點的前一結(jié)點,修正這個結(jié)點的指針。雙向鏈表

35、的每個結(jié)點中包括兩個指針域,分別指向該結(jié)點的前一個結(jié)點和后一個結(jié)點。在雙向鏈表中由任何一個結(jié)點都很容易找到其前面的結(jié)點和后面的結(jié)點,而不需求在上述的插入(及刪除)操作中由頭結(jié)點開場尋覓。定義雙向鏈表的結(jié)點構(gòu)造為typedef struct node DATATYPE info; node *priv, *next;DINKLIST; 下面給出雙向鏈表中插入刪除一個結(jié)點的函數(shù)。操作過程見以下圖:例9-14 將一個結(jié)點插入到雙向鏈表指定結(jié)點之后。insertafter(DINKLIST *current,DINKLIST *new) new-next=current-next; new-privc

36、urrent; current-next-privnew ; current-next-new; 例9-15 將一個結(jié)點插入到雙向鏈表指定結(jié)點之前。 insertbefor(DINKLIST *current,DINKLIST *new) new-nextcurrent; new-priv=current-priv; current-priv=current-priv ; current-priv=new; 例9-16 在雙向鏈表中刪除一個指定結(jié)點。 deleteelement(DINKLIST *current) current-next-priv=current-priv ; curren

37、t-priv-next=current-next; delete(current); 9.3.59.3.5循環(huán)鏈表循環(huán)鏈表 單向鏈表的最后一個結(jié)點的指針域為空NULL。假設(shè)將這個指針里利用起來,以指向單向鏈表的第一個結(jié)點,就組成一個單向循環(huán)鏈表。如圖9-15所示: 9.3.69.3.6鏈表運用實例鏈表運用實例 例9.17 創(chuàng)建包含學(xué)號、姓名節(jié)點的單鏈表。其節(jié)點數(shù)恣意個,表以學(xué)號為序,低學(xué)號的在前,高學(xué)號的在后,以輸入姓名為空作終了。在此鏈表中,要求刪除一個給定姓名的節(jié)點,并插入一個給定學(xué)號和姓名的節(jié)點。 程序如L9-17.c 例9-18 已有a,b兩個鏈表,每個鏈表中的結(jié)點包括學(xué)號,成果,要求

38、把兩個鏈表合并,按學(xué)號升序陳列。 程序如L9-18.c 本章小結(jié)本章小結(jié)1編譯預(yù)處置Ansi C 規(guī)范規(guī)定可以在C源程序中參與一些“預(yù)處置命令,以改良程序環(huán)境,提高編程效率。對于預(yù)處置命令,必需在程序編譯之前,先對這些特殊命令進展“預(yù)處置。經(jīng)過預(yù)處置后程序不再包含預(yù)處置命令了。 C言語提供的預(yù)處置功能主要有以下三種:A、宏定義B、文件包含C、條件編譯分別用宏定義命令,文件包含命令,條件編譯命令來實現(xiàn)。為了與普通C語句相區(qū)別,這些命令以符號“#開頭。2 位運算 C言語提供了位運算的功能, 這使得C言語也能像匯編言語一樣用來編寫系統(tǒng)程序。位運算符C言語提供了六種位運算符: & 按位與| 按位或 按位異或 取反 右移1 按位與運算 按位與運算符&是雙目運算符。其功能是參與運算的兩數(shù)各對應(yīng)的二

溫馨提示

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

評論

0/150

提交評論