第九章 結(jié)構(gòu)體與指針.ppt_第1頁(yè)
第九章 結(jié)構(gòu)體與指針.ppt_第2頁(yè)
第九章 結(jié)構(gòu)體與指針.ppt_第3頁(yè)
第九章 結(jié)構(gòu)體與指針.ppt_第4頁(yè)
第九章 結(jié)構(gòu)體與指針.ppt_第5頁(yè)
已閱讀5頁(yè),還剩65頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第九章 結(jié)構(gòu)體與指針,學(xué)習(xí)目標(biāo) 掌握結(jié)構(gòu)體與聯(lián)合體的概念、語(yǔ)法和應(yīng)用 掌握指針的概念和應(yīng)用 學(xué)會(huì)用指針訪(fǎng)問(wèn)數(shù)組、結(jié)構(gòu)體和函數(shù) 掌握動(dòng)態(tài)存儲(chǔ)分配方法 掌握單鏈表的概念和應(yīng)用,9.1 結(jié)構(gòu)體,結(jié)構(gòu)體的意義 將不同數(shù)據(jù)類(lèi)型的數(shù)據(jù)對(duì)象組織在一起 結(jié)構(gòu)體的應(yīng)用 結(jié)構(gòu)體類(lèi)型聲明與結(jié)構(gòu)體變量聲明 結(jié)構(gòu)體類(lèi)型的嵌套 結(jié)構(gòu)體變量的整體賦值與逐成員賦值 結(jié)構(gòu)體作為函數(shù)參數(shù):發(fā)生整個(gè)結(jié)構(gòu)體的值拷貝操作,結(jié)構(gòu)體嵌套示例,struct Date int year; int month; int day; ; struct Child float height; float weight; Date birthday;

2、char gender; ;,struct Child a; a.height = 0.99; a.birthday.year = 2000; a.birthday.month = 2; a.birthday.day = 14; if( a.height = 1.00 ,結(jié)構(gòu)體應(yīng)用示例,從鍵盤(pán)讀取若干0-5歲兒童的身高、體重、年齡、性別,然后統(tǒng)計(jì)出指定年齡段的兒童的最高、最低身高和平均身高,并輸出相應(yīng)個(gè)體的全部信息,兒童的總數(shù)由鍵盤(pán)輸入,需要統(tǒng)計(jì)的年齡段由鍵盤(pán)輸入,#include #define kMAXCHILDREN 100 struct Child float height; floa

3、t weight; int age; char gender; ;,結(jié)構(gòu)體應(yīng)用示例,void displayChild(struct Child child1) printf( “Age %dn“, child1.age ); printf( “Gender %cn“, child1.gender ); printf( “Height %fn“, child1.height ); printf( “Weight %fn“, child1.weight ); struct Child inputChild() struct Child child1; printf( “Age: “ ); sca

4、nf( “%d“, ,結(jié)構(gòu)體應(yīng)用示例,int main() struct Child surveysetkMAXCHILDREN, tallest, shortest; int i, n, age, count; float sum = 0; printf( “Number of children: “ ); scanf( “%d“, ,結(jié)構(gòu)體應(yīng)用示例,while( age = 0 ) tallest.height = 0; shortest.height = 2; sum = 0; count = 0; for( i = 0; i tallest.height ) tallest = sur

5、veyseti; if( surveyseti.height shortest.height) shortest = surveyseti; ,結(jié)構(gòu)體應(yīng)用示例,printf( “The tallest:n“ ); displayChild( tallest ); printf( “The shortest:n“ ); displayChild( shortest ); printf( “The average height: %fn“, sum / count ); printf( “Enter the age of children you want to count:“ ); scanf(

6、 “%d“, / while( age = 0 ) ,結(jié)構(gòu)體指針,指向結(jié)構(gòu)體變量的指針 聲明格式:struct 結(jié)構(gòu)體名* 結(jié)構(gòu)體指針變量名; 例:struct Child; struct Child* p; struct Child a = 0.83, 30.0, 5, M ; p = ,9.2 指 針,指針的意義與作用 指針的聲明與使用 指針運(yùn)算 指針與其他數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系 動(dòng)態(tài)內(nèi)存分配 指針與函數(shù),指針的意義與作用,指針的意義:通過(guò)地址訪(fǎng)問(wèn)數(shù)據(jù)或函數(shù) 指針的使用場(chǎng)合 函數(shù)參數(shù):提高函數(shù)參數(shù)的傳遞效率 以緊縮格式引用大型數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)共享 構(gòu)造復(fù)雜數(shù)據(jù)結(jié)構(gòu):與其他數(shù)據(jù)結(jié)構(gòu)有機(jī)組合 記錄數(shù)

7、據(jù)間的聯(lián)系 動(dòng)態(tài)內(nèi)存分配:構(gòu)造并訪(fǎng)問(wèn)匿名數(shù)據(jù)對(duì)象 動(dòng)態(tài)存儲(chǔ)管理,指針的聲明,指針是一種數(shù)據(jù)類(lèi)型 格式:目標(biāo)數(shù)據(jù)對(duì)象的數(shù)據(jù)類(lèi)型 *指針變量名; 例:int *p; float *q; char *s;,多個(gè)指針變量聲明指針 每個(gè)變量名前都需使用指針?lè)?hào) 例:int *p, *q;,指針數(shù)據(jù)對(duì)象與目標(biāo)數(shù)據(jù)對(duì)象,指針數(shù)據(jù)對(duì)象 指針變量:指針型式定義的變量(數(shù)據(jù)對(duì)象) 指針變量的值:內(nèi)存地址值,一般為其他數(shù)據(jù)對(duì)象地址 目標(biāo)數(shù)據(jù)對(duì)象:指針?biāo)赶虻臄?shù)據(jù)對(duì)象 和指針數(shù)據(jù)對(duì)象不是一回事,一般位于不同的地址 一般匿名,在使用時(shí)指定,指針的初始化,未初始化的指針?lè)浅NkU(xiǎn) 既可能指向未知地址,也可能指向未初始化的目

8、標(biāo)對(duì)象 指針的初始化方法 目標(biāo)數(shù)據(jù)對(duì)象的數(shù)據(jù)類(lèi)型 *指針變量名 = 初始值; 例:int n = 100; int *p = / a為數(shù)組名,表示數(shù)組首地址,關(guān)于指針初始化的說(shuō)明,指針的初始化是指針數(shù)據(jù)對(duì)象的初始化,而不是目標(biāo)數(shù)據(jù)對(duì)象的初始化 目標(biāo)數(shù)據(jù)對(duì)象的數(shù)據(jù)類(lèi)型必須與指針定義一致 可以使用其他同類(lèi)型指針變量進(jìn)行初始化 初始值為某個(gè)數(shù)據(jù)對(duì)象的地址,該數(shù)據(jù)對(duì)象必須已定義 普通整型數(shù)據(jù)一般不能作為初始值,否則會(huì)造成程序?yàn)?zāi)難 可以將指針初始化為空指針,即設(shè)為0,使其不指向任何對(duì)象,指針的算術(shù)運(yùn)算,指針遞增遞減運(yùn)算 向下(遞增)或向上(遞減)移動(dòng)一個(gè)數(shù)據(jù)單位 例:int a8; int *p = a

9、; p+; / 使p指向a1 指針加減某個(gè)整數(shù)運(yùn)算 向下(加)或向上(減)移動(dòng)n個(gè)數(shù)據(jù)單位 例:int a8; int *p = a; p + 2; / 使p指向a2 指針相減運(yùn)算 確定兩個(gè)指針間的數(shù)據(jù)個(gè)數(shù),不是字節(jié)數(shù) 例:int a8; int *p1 = a, *p2 = p2 p1 7,指針的關(guān)系運(yùn)算與賦值運(yùn)算,指針的關(guān)系運(yùn)算 只能判斷指針是否為空指針 例:int a8; int *p = a; if( p != 0 ) *p = 100; 指針的賦值運(yùn)算 將變量地址賦給指針:int n; int *p; p = ,指針操作示例一,使用指針將輸入的兩個(gè)整數(shù)交換順序,#include in

10、t main() int m, n,*pm,*pn, temp; / 定義整型變量和指針變量 pm = ,問(wèn)題:使用下邊的語(yǔ)句替換行不行?,指針操作示例二,使用指針輸入輸出數(shù)組元素,#include int main() float data5, *pf = data; int k; printf(“Input data:n“); for(k = 0; k 5; k+) scanf(“%f“, pf + k); / 通過(guò)指針進(jìn)行數(shù)組元素的輸入 for(k = 0; k 5; k+) printf(“%f,“, *pf ); pf+; / 通過(guò)指針輸出數(shù)組元素 pf = data; / 指針重新

11、指向數(shù)組的首地址 printf(“n“); for(k = 0; k 5; k+) printf(“%f, “, *(pf + k); / 依次輸出數(shù)組各元素 printf(“n“); return 0; ,pf + k s = “C Programming”; 錯(cuò)誤例:char s14; s = “C Programming”; s為數(shù)組名,不可整體賦值 指針與常量 正確例:char* name = “Qiao Lin”; 錯(cuò)誤例:name1 = J; name指向常量,其所有字符不可變,指針與數(shù)組的關(guān)系一,指針數(shù)組:聲明元素類(lèi)型為指針的數(shù)組 格式:類(lèi)型標(biāo)識(shí)* 數(shù)組名整型常量表達(dá)式; 例:i

12、nt* p8; p為數(shù)組,包含8個(gè)元素,元素的數(shù)據(jù)類(lèi)型為int* 使用方法 int a8; p1 = a; / 將數(shù)組a的基地址賦給p1 *p1 = 10; / 將a0設(shè)為10 p1+; / 將指針p1向前移動(dòng)一個(gè)單位,指向a1 (*p1)+; / 遞增a1的值 *p1+ = 20; / 將a1設(shè)為20,然后p1指向a2,指針數(shù)組關(guān)系圖,int* p8;,指針數(shù)組關(guān)系圖,int* p8; int a8;,指針數(shù)組關(guān)系圖,int* p8; int a8; p1 = a;,指針數(shù)組關(guān)系圖,int* p8; int a8; p1 = a; *p1 = 10;,指針數(shù)組關(guān)系圖,int* p8; int

13、 a8; p1 = a; *p1 = 10;,p1+;,指針數(shù)組關(guān)系圖,int* p8; int a8; p1 = a; *p1 = 10;,p1+; (*p1)+;,指針數(shù)組關(guān)系圖,int* p8; int a8; p1 = a; *p1 = 10;,p1+; (*p1)+; *p1+ = 20;,指針應(yīng)用示例一,輸出1月至12月的月名,#include char* month_name( int n ) static char* name = “None”, “Jan”, “Feb”, “Mar“, “Apr“, “May“, “Jun”, ”Jul“, “Aug“, “Sep“, “Oc

14、t“, “Nov“, “Dec“ ; return ( ( n 12 ) ? name0 : namen ); int main() int i; for( i = 1; i 13; i+ ) printf( “%sn“, month_name(i) ); return 1; ,使用字符指針數(shù)組,主函數(shù)參數(shù),程序的命令行參數(shù)如何傳遞給主函數(shù)? 例:rename filename1 filename2 主函數(shù)格式:int main(int argc, char* argv); argc為命令行參數(shù)個(gè)數(shù) argv為命令行參數(shù)數(shù)組:argv0為命令名,argv1為第一個(gè)參數(shù),argv2為第二個(gè)參數(shù),

15、等等 函數(shù)返回值 表示主程序是否成功執(zhí)行 如果執(zhí)行時(shí)發(fā)生錯(cuò)誤,應(yīng)返回具有特殊意義的錯(cuò)誤碼,指針應(yīng)用示例二,編寫(xiě)程序 echo,實(shí)現(xiàn)其命令行參數(shù)的輸出:當(dāng)用戶(hù)輸入 “echo Hello world” 后,系統(tǒng)輸出“Hello world”,#include int main( int argc, char *argv ) while( argc 1 ) +argv; / 第一個(gè)參數(shù)是程序名,跳過(guò)不取 printf( “%s; “, *argv ); argc; ,指針與數(shù)組的關(guān)系二,數(shù)組指針:指向數(shù)組整體的指針 格式:類(lèi)型標(biāo)識(shí) (*數(shù)組名)整型常量表達(dá)式; 例:int (*p)8; p為指針,

16、指向包含8個(gè)整數(shù)元素的數(shù)組 使用方法 int a28; p = a; / 將數(shù)組a首行的基地址賦給p (*p)0 = 10; / 將a00設(shè)為10 p+; / 指針p向前移動(dòng)一個(gè)單位,指向a的下一行行首 *p = 20; / 遞增a10的值 *( *(p 1) + 2 ) = 30; / 將a02設(shè)為30,數(shù)組指針關(guān)系圖,int (*p)8;,數(shù)組指針關(guān)系圖,int (*p)8; int a28;,數(shù)組指針關(guān)系圖,int (*p)8; int a28; p = a;,數(shù)組指針關(guān)系圖,int (*p)8; int a28; p = a; (*p)0 = 10;,數(shù)組指針關(guān)系圖,int (*p)8

17、; int a28; p = a; (*p)0 = 10;,p+;,數(shù)組指針關(guān)系圖,int (*p)8; int a28; p = a; (*p)0 = 10;,p+; *p = 20;,數(shù)組指針關(guān)系圖,int (*p)8; int a28; p = a; (*p)0 = 10;,p+; *p = 20; *(*(p 1) + 2) = 30;,指針應(yīng)用示例三,用指向數(shù)組的指針處理二維數(shù)組,#include int main() int array34 = 1,3,5,7, 9,11,13,15, 17,19,21,23 ; int i, j, (*ptr)4; ptr = array; /

18、ptr指向二維數(shù)組起始位置 for( i = 0; i 3; i+ ) for( j = 0; j 4; j+ ) printf( “%dt“, *(*(ptr + i) + j) ); / 逐個(gè)輸出每個(gè)元素 printf( “n“ ); ,指針與函數(shù),指針作為函數(shù)參數(shù) 目的:傳遞目標(biāo)數(shù)據(jù)對(duì)象的地址而不是值 例:void Display( struct Child c ); 調(diào)用 Display() 時(shí)發(fā)生值拷貝操作,傳遞效率太低 例:void Display( struct Child* pc ); 調(diào)用Display() 時(shí)僅發(fā)生pc值(目標(biāo)數(shù)據(jù)對(duì)象的地址)的拷貝操作,不拷貝目標(biāo)結(jié)構(gòu)體的任

19、何數(shù)據(jù) 返回指針類(lèi)型的函數(shù) 不能返回在函數(shù)內(nèi)部分配的局部數(shù)據(jù)對(duì)象 (?),動(dòng)態(tài)內(nèi)存分配,動(dòng)態(tài)內(nèi)存分配的目的 在執(zhí)行過(guò)程中為數(shù)據(jù)對(duì)象分配合適的存儲(chǔ)空間 動(dòng)態(tài)內(nèi)存分配的使用場(chǎng)合 不能在執(zhí)行前確定數(shù)據(jù)對(duì)象的存儲(chǔ)空間大小 不適合在執(zhí)行前為數(shù)據(jù)對(duì)象分配存儲(chǔ)空間 動(dòng)態(tài)內(nèi)存分配函數(shù):“stdlib.h” 或 “malloc.h” void* malloc( size_t size ); void free( void* memblock );,動(dòng)態(tài)內(nèi)存分配示例一,編寫(xiě)函數(shù),將某個(gè)字符轉(zhuǎn)換為字符串,#include typedef char* string; string CharToString(char

20、ch) char* p; p = malloc( 2 ); p0 = ch; p1 = 0; return( p ); ,string CharToString(char ch) char array2; array0 = ch; array1 = 0; return( array ); ,正確代碼:,錯(cuò)誤代碼: array為局部變量,不能作為函數(shù)返回值返回,動(dòng)態(tài)內(nèi)存分配示例二,使用動(dòng)態(tài)內(nèi)存分配技術(shù)重新實(shí)現(xiàn)兒童信息統(tǒng)計(jì)程序,#include / 其它部分同結(jié)構(gòu)體應(yīng)用示例 void main() struct Child *surveyset, tallest, shortest; / 動(dòng)態(tài)分配

21、內(nèi)存 surveyset = ( struct Child* )malloc( n*sizeof(struct Child) ); for( i = 0; i n; i+ ) surveyseti = inputChild(); free( surveyset ); / 程序結(jié)束前釋放動(dòng)態(tài)分配的內(nèi)存 ,關(guān)于動(dòng)態(tài)內(nèi)存分配的說(shuō)明,有需要再分配,不需要不分配 有分配就有釋放 malloc() 與 free() 一般在程序代碼的相同層次成對(duì)出現(xiàn) 例外情況:在函數(shù)內(nèi)部分配的匿名數(shù)據(jù)對(duì)象在函數(shù)退出后仍然存在 構(gòu)造復(fù)雜數(shù)據(jù)結(jié)構(gòu)時(shí)動(dòng)態(tài)存儲(chǔ)分配非常有用,9.3 鏈 表,鏈表的定義 動(dòng)態(tài)數(shù)據(jù)結(jié)構(gòu),可表示順序訪(fǎng)問(wèn)的

22、線(xiàn)性數(shù)據(jù)集 結(jié)點(diǎn)(node):物理上不相鄰,邏輯上的相鄰關(guān)系由指針維持 表頭(head)、表尾(tail) 單鏈表、雙鏈表、循環(huán)鏈表,結(jié)點(diǎn)的存儲(chǔ)格式,兒童信息結(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu) 包含數(shù)據(jù)域(信息)與指針域(鏈接)兩部分,struct Child float height; float weight; int age; char gender; struct Child *next; ;,鏈表基本操作,鏈表的創(chuàng)生、銷(xiāo)毀與清空 元素的追加、插入、刪除 鏈表的遍歷、查找與比較 鏈表的狀態(tài)查詢(xún),鏈表創(chuàng)生示例,構(gòu)造兒童信息鏈表,#include #include struct Child / 鏈表結(jié)點(diǎn)結(jié)構(gòu)體

23、/ 結(jié)點(diǎn)數(shù)據(jù) float height; float weight; int age; char gender; / 后繼結(jié)點(diǎn)地址 struct Child *next; ; typedef struct Child ChildNode;,鏈表創(chuàng)生示例,void inputChild( ChildNode* child ) / 結(jié)點(diǎn)數(shù)據(jù)輸入函數(shù) printf( “Age: “ ); scanf( “%d“, ,鏈表創(chuàng)生示例,ChildNode* createList( int n ) / 生成鏈表 ChildNode *p, *child; int i; / 建立一個(gè)空的頭結(jié)點(diǎn) child =

24、 (ChildNode*)malloc(sizeof(ChildNode); childnext = NULL; / 初始化指針域 for( i = n; i 0; i ) / 依次建立并向表頭插入結(jié)點(diǎn) / 創(chuàng)建新結(jié)點(diǎn) p = (ChildNode *)malloc(sizeof(ChildNode); inputChild( p ); / 輸入數(shù)據(jù)到新結(jié)點(diǎn) / 將新結(jié)點(diǎn)插入到表頭結(jié)點(diǎn)之后 pnext = childnext; childnext = p; return child; ,鏈表創(chuàng)生示例,int main() ChildNode *childList = NULL; int n;

25、printf( “Number of children: “ ); scanf( “%d“, / 構(gòu)造鏈表 ,鏈表創(chuàng)生示例,使用模塊劃分技術(shù)構(gòu)造兒童信息鏈表,/ childlist.h struct Child / 鏈表結(jié)點(diǎn)結(jié)構(gòu)體 / 結(jié)點(diǎn)數(shù)據(jù) float height; float weight; int age; char gender; / 后繼結(jié)點(diǎn)地址 struct Child *next; ; typedef struct Child ChildNode; void inputChild( ChildNode* child ); ChildNode* createList( int

26、n );,鏈表創(chuàng)生示例,/ childlist.c #include #include void inputChild( ChildNode* child ) / 結(jié)點(diǎn)數(shù)據(jù)輸入函數(shù) ChildNode* createList( int n ) / 生成鏈表 ,鏈表創(chuàng)生示例,/ main.c #include #include #include “childlist.h” int main() ,鏈表遍歷示例,構(gòu)造并輸出兒童信息鏈表,/ childlist.h struct Child / 鏈表結(jié)點(diǎn)結(jié)構(gòu)體 / 結(jié)點(diǎn)數(shù)據(jù) float height; float weight; int age; c

27、har gender; / 后繼結(jié)點(diǎn)地址 struct Child *next; ; typedef struct Child ChildNode; void inputChild( ChildNode* child ); ChildNode* createList( int n ); void printList( ChildList* child );,鏈表遍歷示例,/ childlist.c #include #include void printList( ChildList* child ) ChildNode *current; current = child; / 遍歷指針初始狀

28、態(tài)指向表頭 while( currentnext != NULL ) current = currentnext; / 當(dāng)前指針移動(dòng)到下一個(gè)結(jié)點(diǎn) printf( “Age %dt“, currentage ); printf( “Gender %ct“, currentgender ); printf( “Height %ft“, currentheight ); printf( “Weight %fn“, currentweight ); ,鏈表遍歷示例,/ main.c #include #include #include “childlist.h” int main() ChildNod

29、e *childList = NULL; int n; printf( “Number of children: “ ); scanf( “%d“, ,鏈表插入操作,順序存儲(chǔ)結(jié)構(gòu)中元素的插入 根據(jù)插入位置的不同,需要移動(dòng)部分?jǐn)?shù)據(jù) 平均需要移動(dòng)一半長(zhǎng)度的數(shù)據(jù) 鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)中元素的插入 不需要移動(dòng)元素,只需要修改鏈表指針 元素插入位置 表頭、表尾、表中,鏈表表頭插入,p-next = head; head = p;,p-next = head-next; head-next = p;,鏈表表尾插入,q = head; while( q-next != NULL ) q = q-next; q-next = p;,鏈表表中插入,q = head; while( q-next.data != x ) q = q-next; p-next = q-next; q-next = p;,鏈表插入示例,按年齡由小到大的次序建立一個(gè)兒童信息鏈表,并輸出鏈表中的數(shù)據(jù),/ childlist.h struct Child / 鏈表結(jié)點(diǎn)結(jié)構(gòu)體 float height; float weight; int age; char gender; struct Child *next; ; typedef struct Child ChildNode; void inputChild(

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論