算法與數(shù)據(jù)結(jié)構(gòu)-C語言描述(第二版):C語言中的指針_第1頁
算法與數(shù)據(jù)結(jié)構(gòu)-C語言描述(第二版):C語言中的指針_第2頁
算法與數(shù)據(jù)結(jié)構(gòu)-C語言描述(第二版):C語言中的指針_第3頁
算法與數(shù)據(jù)結(jié)構(gòu)-C語言描述(第二版):C語言中的指針_第4頁
算法與數(shù)據(jù)結(jié)構(gòu)-C語言描述(第二版):C語言中的指針_第5頁
已閱讀5頁,還剩38頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、算法與數(shù)據(jù)結(jié)構(gòu)C語言描述(第二版)高巖課程目標 學(xué)習掌握基本數(shù)據(jù)結(jié)構(gòu)與基本運算 訓(xùn)練數(shù)據(jù)抽象能力 訓(xùn)練算法設(shè)計與描述能力 提高程序(軟件)設(shè)計能力課程安排 108個學(xué)時(5學(xué)分)其中:上課73學(xué)時,試驗36學(xué)時 先期課程C程序設(shè)計,面向?qū)ο蟪绦蛟O(shè)計,離散數(shù)學(xué)教材 算法與數(shù)據(jù)結(jié)構(gòu),張乃孝編,高等教育出版社 數(shù)據(jù)結(jié)構(gòu),嚴蔚敏編,清華大學(xué)出版社 數(shù)據(jù)結(jié)構(gòu)題集,嚴蔚敏等編,清華大學(xué)出版社 C語言中的指針與函數(shù)語言中的指針與函數(shù)A 指指 針針 一個指針是一個特殊變量,它的值是另一一個指針是一個特殊變量,它的值是另一個變量的地址。個變量的地址。 除寄存器除寄存器(register)變量外,所有的變量均變量

2、外,所有的變量均有地址。地址是變量在內(nèi)存中存放的位置。有地址。地址是變量在內(nèi)存中存放的位置。在聲明一個指針變量時,我們在變量名字在聲明一個指針變量時,我們在變量名字前加一個星號前加一個星號 *。A.1 指向變量的指針指向變量的指針 聲明字符型變量聲明字符型變量 a 和指向字符型的指針變和指向字符型的指針變量量 p: char a=b; char *p; 此處的此處的 p 是指針變量,是指針變量,p 前面的前面的 * 用來聲用來聲明明 p 為一個指針,即為一個指針,即 p 是存放一個變量地是存放一個變量地址的變量,址的變量,p 指向的變量是字符型的,即指向的變量是字符型的,即 p 存放字符型變量

3、的地址。存放字符型變量的地址。 指針變量指針變量 p 在初始化之前,它的當前值是不在初始化之前,它的當前值是不定的,語句定的,語句 p= &a; 是將字符變量是將字符變量 a 的地址賦給指向字符型的指的地址賦給指向字符型的指針變量針變量 p, 符號符號 & 在這里作為一元運算符,是地址運算在這里作為一元運算符,是地址運算符,符,&a 是求變量是求變量 a 的地址。的地址。 上述語句執(zhí)行后,在上述語句執(zhí)行后,在 p 內(nèi)存放內(nèi)存放 a 的地址,重的地址,重要的是要的是 p 與與 a 的類型要匹配。的類型要匹配。 用用 *p 表示指針表示指針p所指的對象,即先取出所指的對象,

4、即先取出 p 中的值中的值,得一個地址,再通過此地址得到需得一個地址,再通過此地址得到需要的對象,因此下面的兩個語句輸出同樣要的對象,因此下面的兩個語句輸出同樣的結(jié)果的結(jié)果b: printf(a is %cn,a); printf(a is %cn,*p); 我們可用變量的名字我們可用變量的名字 a,也可用指向變量,也可用指向變量 a 的指針變量的指針變量 p。這樣,要將。這樣,要將 a 內(nèi)的原有值內(nèi)的原有值b 改成改成 d,可直接將可直接將 d 賦給變量賦給變量 a,也可,也可間接地使用指針變量間接地使用指針變量 p,其程序片段為:,其程序片段為: p=&a; /* 初始化初始化 p

5、 */ a=d; /* 將將 d 直接賦給直接賦給 a */ *p=d; /*通過指針變量通過指針變量 p 將將 d 賦給賦給 a */ 先討論指向數(shù)組元素的指針。先討論指向數(shù)組元素的指針。 用下面語句聲明一個字符型數(shù)組和一個指向字符用下面語句聲明一個字符型數(shù)組和一個指向字符型變量的指針:型變量的指針: char line100,*p; 可用下面的語句給可用下面的語句給 line 的前兩個元素賦值:的前兩個元素賦值: line0=a; line1=b; 也可用指針,先對也可用指針,先對 p 初始化使其指向數(shù)組初始化使其指向數(shù)組 line 的的首址:首址: p=&line0; /* 第第

6、 0 個元素的地址個元素的地址 */ 或直接寫成:或直接寫成: p=line; /* 數(shù)組名字是數(shù)組的首址數(shù)組名字是數(shù)組的首址 */A.2 指向數(shù)組的指針指向數(shù)組的指針 然后可用下面兩個語句給數(shù)組的前兩個元然后可用下面兩個語句給數(shù)組的前兩個元素賦值:素賦值: *p=a; *(p+1)=b; 對于每個賦值,編譯程序?qū)⑹紫扔嬎阍貙τ诿總€賦值,編譯程序?qū)⑹紫扔嬎阍氐牡刂返牡刂? 數(shù)組名字數(shù)組名字 line即是數(shù)組的首地址,即是數(shù)組的首地址,line 加上增量加上增量 0,line 加上增量加上增量 1,分別是,分別是前兩個元素的地址。前兩個元素的地址。 連續(xù)執(zhí)行下面兩個語句連續(xù)執(zhí)行下面兩個語句

7、*p+=a; *p+=b; /* 運算符運算符*與與+的優(yōu)先級相同,的優(yōu)先級相同, 結(jié)合方向結(jié)合方向是是 “從右到左從右到左”*p+ 即即 *(p+) */ 指針指針 p 將兩次增將兩次增1,最終指向,最終指向 line2 的地的地址。址。 假設(shè)有整型數(shù)組和指向整型量的指針:假設(shè)有整型數(shù)組和指向整型量的指針: int num10,*q=num; q 指向指向 num0的地址,的地址, 當當 q 增增 1 時,時,q 指向指向 num1的地址,要移動的地址,要移動 2 個或個或 4 個字節(jié)個字節(jié)(依賴于依賴于不同的計算機不同的計算機); 而指向字符型的指針增而指向字符型的指針增 1 時,只時,只

8、移動一個字節(jié),這就是指針變量與其指向的變量移動一個字節(jié),這就是指針變量與其指向的變量的類型必須要匹配的道理。的類型必須要匹配的道理。 若兩個指針指向同一數(shù)組,這兩個指針也可以做若兩個指針指向同一數(shù)組,這兩個指針也可以做比較運算。比較運算。 以上討論的是指向數(shù)組元素的指針,下面再以上討論的是指向數(shù)組元素的指針,下面再簡單介紹指向一維數(shù)組的指針:簡單介紹指向一維數(shù)組的指針: int a34,(*pa)4; pa=a;第一行聲明的第一行聲明的 pa 是一個指針,指向有是一個指針,指向有4 個元個元素的一維整型數(shù)組;素的一維整型數(shù)組;第二行通過對第二行通過對pa賦值,使得賦值,使得 pa 等于等于 a

9、00 的地址,的地址,pa+1 要后移要后移4 個整數(shù),即個整數(shù),即pa+1 指向指向 a10 的地址,的地址,*(pa+1)+3 指向指向a13的地址,的地址,*(*(pa+2)+1) 是是a21 的值的值 。 也可建立一個指針數(shù)組,它的每個元素均也可建立一個指針數(shù)組,它的每個元素均是一個指針,存放地址,下面的語句是一個指針,存放地址,下面的語句 char *ap3; 聲明聲明 ap 是一個指向字符型的指針數(shù)組,是一個指向字符型的指針數(shù)組,ap 的每個元素存放一個字符串的首址。的每個元素存放一個字符串的首址。A.3 指針數(shù)組指針數(shù)組 若我們用內(nèi)存動態(tài)存儲區(qū)分配函數(shù)分配每個字符串若我們用內(nèi)存動

10、態(tài)存儲區(qū)分配函數(shù)分配每個字符串的空間:的空間: api=(char *)malloc(sizeof( 字符串字符串); 則則 api 指向分配的相應(yīng)字符串區(qū)域的首址。例如:指向分配的相應(yīng)字符串區(qū)域的首址。例如: ap0 存放存放 science 的首址的首址 ap1 存放存放 technology 的首址的首址 ap2 存放存放 art 的首址的首址 可以如下表示:可以如下表示: ap0=(char *)malloc(sizeof( science); ap1=(char *)malloc(sizeof(techonology); ap2=(char *)malloc(sizeof(art);

11、 A.4 指向結(jié)構(gòu)的指針指向結(jié)構(gòu)的指針 可定義一個結(jié)構(gòu)數(shù)組,然后用指針指向此數(shù)組的可定義一個結(jié)構(gòu)數(shù)組,然后用指針指向此數(shù)組的第一個元素,這等同于我們以前討論的指向數(shù)組第一個元素,這等同于我們以前討論的指向數(shù)組元素的指針。例如:元素的指針。例如:struct exp /* 定義結(jié)構(gòu)定義結(jié)構(gòu) exp */ char c; int i; struct exp ae10,*p; /* 定義結(jié)構(gòu)數(shù)組定義結(jié)構(gòu)數(shù)組 ae 和指向結(jié)構(gòu)的指針和指向結(jié)構(gòu)的指針 p */ p=ae; /* 使使 p 指向數(shù)組的首址,即指向數(shù)組的首址,即 ae0 的地址的地址 */ p-c=a; /* 元素元素ae0 的成員的成員c

12、 為為 a */ p-i=0; /* 元素元素 ae0 的成員的成員 i 為為 0 */ p+; /* 使使 p 指向指向 ae1 */ p-c=b; /* 元素元素 ae1 的成員的成員 c 為為 b */ 當當 p 是指向結(jié)構(gòu)的指針時,運算符是指向結(jié)構(gòu)的指針時,運算符 - 是成員運算符,是成員運算符, p-c 等價于等價于 (*p).c 一個結(jié)構(gòu)中的成員也可以是一個指針,此一個結(jié)構(gòu)中的成員也可以是一個指針,此指針可指向同種類型的另一個結(jié)構(gòu),稱自指針可指向同種類型的另一個結(jié)構(gòu),稱自引用結(jié)構(gòu),例如引用結(jié)構(gòu),例如struct self char c; struct self *next;;str

13、uct self *p; 聲明了聲明了 p 是一個指向結(jié)構(gòu)是一個指向結(jié)構(gòu) struct self 的指的指針變量,鏈表常用類似的結(jié)構(gòu)表示,針變量,鏈表常用類似的結(jié)構(gòu)表示,p 指指向鏈表中的一個元素(結(jié)構(gòu)類型),要存向鏈表中的一個元素(結(jié)構(gòu)類型),要存取表中的下一個元素,可以用取表中的下一個元素,可以用 p=p-next; 因為在因為在 p-next 中存放下一個元素的地址。中存放下一個元素的地址。A.5 補充補充(指針與數(shù)組指針與數(shù)組) 一維數(shù)組一維數(shù)組 二維數(shù)組二維數(shù)組 二維數(shù)組與指針二維數(shù)組與指針 指針數(shù)組指針數(shù)組 指針數(shù)組指針數(shù)組與指針的指針與指針的指針 指向數(shù)組的指針指向數(shù)組的指針 多

14、維數(shù)組多維數(shù)組p a0 a1 a2 . aint a10, *p; p=a;*p *a a0*(p+i) *(a+i) ai一維數(shù)組一維數(shù)組 a0 a00 a01 a02 . a10 a11 a12 . a1 a2 .a二維數(shù)組二維數(shù)組: int a1010; aij *(*(a+i)+j) *(ai+j)#includemain() /* 數(shù)組的初始化數(shù)組的初始化*/ int a44=1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16; int i,j: for (i=0; i4; i+) for( j=0; j4; j+) printf(“%10d”, *(ai

15、+j) ); printf(“n”); p a0 a00 a01 a02 . a10 a11 a12 . a1 a2 . a 二維數(shù)組與指針二維數(shù)組與指針: int a1010; int *p; p=(int *) a; aij *( (p+i*10)+j ) *(ai+j)#includemain() int a44=1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16; int *p, i, j; p=(int*)a; for (i=0; i4; i+) for( j=0; j4; j+) printf(“%10d”, *( (p+i*4) +j) ); prin

16、tf(“n”); p a00 a01 a02 . a10 a11 a12 . . a int a1010; int *p10; /*指針數(shù)組指針數(shù)組*/ for(i=0; i10; i+) pi=ai; aij *(*(p+i)+j) *(pi+j) *(ai+j) a0 int a44=1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16; int *p4, i, j; for (i=0; i4; i+) pi=ai; for (i=0; i4; i+) for( j=0; j4; j+) printf(“%10d”, *(* (p+i) +j) ); printf

17、(“n”); p a00 a01 a02 . a10 a11 a12 . . a /*指針數(shù)組指針數(shù)組與指針的指針與指針的指針*/ int a1010; int *p10,*q ; for(i=0; i4; i+) pi=ai; q=p; aij *(*(q+i)+j) *(pi+j) *(ai+j) a0 q int a44=1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16; int *p4, *q, i, j; for (i=0; i4; i+) pi=ai; q=p; for (i=0; i4; i+) for( j=0; j4; j+) printf(“%

18、10d”, *(* (q+i) +j) ); printf(“n”); p a0 a00 a01 a02 . a10 a11 a12 . a1 a2 . a int a1010; int (*p)10; /*指向數(shù)組的指針指向數(shù)組的指針*/ p=(int( *) 10) a0; aij *( *(p+i)+j ) *(ai+j) int a44=1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16; int ( *p)4, i, j; p=(int(*)4)a0; for (i=0; i4; i+) for( j=0; j4; j+) printf(“%10d”, *

19、(* (p+i) +j) ); printf(“n”); p a0 a00 a000 a001 a002 . a010 a011 a012 . a100 a101 a102 . a01 a02 . a10 a11 a12 . a1 a2 . a多維數(shù)組多維數(shù)組注:圖中畫出的左邊兩個數(shù)組并不是數(shù)組。B. 函數(shù)函數(shù) 一個一個 C 程序由幾個函數(shù)組成。在調(diào)用函數(shù)時,實程序由幾個函數(shù)組成。在調(diào)用函數(shù)時,實際傳到函數(shù)的信息稱為實在參數(shù)際傳到函數(shù)的信息稱為實在參數(shù)(argument),而,而函數(shù)中保存要得到信息的參數(shù)稱為形式參數(shù)函數(shù)中保存要得到信息的參數(shù)稱為形式參數(shù)(parameter)。 void f(

20、int x); 說明函數(shù)說明函數(shù) f 需要一個整型參數(shù),無返回值到調(diào)用需要一個整型參數(shù),無返回值到調(diào)用它的函數(shù)中。它的函數(shù)中。 函數(shù)原型寫出了此函數(shù)所需要的參數(shù)個數(shù)及其類函數(shù)原型寫出了此函數(shù)所需要的參數(shù)個數(shù)及其類型,如果函數(shù)不需要參數(shù),則圓括號內(nèi)為空或?qū)懶?,如果函?shù)不需要參數(shù),則圓括號內(nèi)為空或?qū)?void, 函數(shù)名字前面的類型指出函數(shù)要返回的表函數(shù)名字前面的類型指出函數(shù)要返回的表達式的值的類型,若此函數(shù)無返回值,則此類型達式的值的類型,若此函數(shù)無返回值,則此類型寫成寫成 void。B.1函數(shù)的實在參數(shù)函數(shù)的實在參數(shù)值傳送值傳送 在調(diào)用函數(shù)時,先將實在參數(shù)(通常是一個表達式)的在調(diào)用函數(shù)時,先將

21、實在參數(shù)(通常是一個表達式)的值計算出來,然后傳給函數(shù)的形式參數(shù),因此,形式參值計算出來,然后傳給函數(shù)的形式參數(shù),因此,形式參數(shù)得到的是實在參數(shù)值的拷貝。如果在被調(diào)用函數(shù)內(nèi)改數(shù)得到的是實在參數(shù)值的拷貝。如果在被調(diào)用函數(shù)內(nèi)改動形式參數(shù),則只改變了這個拷貝的值,而調(diào)用函數(shù)中動形式參數(shù),則只改變了這個拷貝的值,而調(diào)用函數(shù)中的實在參數(shù)并沒有改變。這就是的實在參數(shù)并沒有改變。這就是“值傳送值傳送”。考慮以下??紤]以下函數(shù):函數(shù): void f(int j) j-; printf(j is %dn,j); /* 輸出的結(jié)果是輸出的結(jié)果是 2 */ i=3; f(i); printf( i is %d n

22、,i); /* 輸出的輸出的 i 仍是仍是3 */ B.2函數(shù)的實在參數(shù)函數(shù)的實在參數(shù) 地址傳送地址傳送 有時我們在函數(shù)調(diào)用時,需要直接將被調(diào)有時我們在函數(shù)調(diào)用時,需要直接將被調(diào)函數(shù)中對形式參數(shù)的修改體現(xiàn)在調(diào)用函數(shù)函數(shù)中對形式參數(shù)的修改體現(xiàn)在調(diào)用函數(shù)的某個實在變量上,此時要用這個變量的的某個實在變量上,此時要用這個變量的地址作為實在參數(shù)傳送,相應(yīng)的形式參數(shù)地址作為實在參數(shù)傳送,相應(yīng)的形式參數(shù)應(yīng)該是與這個實在變量類型一致的指針類應(yīng)該是與這個實在變量類型一致的指針類型。型。 例如,函數(shù):例如,函數(shù): void g(int *k) *k=2; 形式參數(shù)是一個指向整型變量的指針,在此形式參數(shù)是一個指向

23、整型變量的指針,在此函數(shù)內(nèi)將函數(shù)內(nèi)將 2 賦給用指針賦給用指針 k 指向的整型變量,指向的整型變量,調(diào)用此函數(shù)的一個例子是調(diào)用此函數(shù)的一個例子是 void main(void) int i; g(&i); printf(i=%dn,i); /* 輸出的結(jié)果是輸出的結(jié)果是 2 */ 由于數(shù)組名提供的就是數(shù)組的開始地址,由于數(shù)組名提供的就是數(shù)組的開始地址,所以可作為實在參數(shù)和要求與數(shù)組元素類所以可作為實在參數(shù)和要求與數(shù)組元素類型一致的指針類型的形式參數(shù)對應(yīng)。例如:型一致的指針類型的形式參數(shù)對應(yīng)。例如: int getline(char *p,int i); int n; char line

24、100; . n=getline(line,100); 上面的程序片段調(diào)用函數(shù)上面的程序片段調(diào)用函數(shù) getline,需要一,需要一個指向字符的指針和一個整型量作實參,個指向字符的指針和一個整型量作實參,因數(shù)組名字表示地址,我們傳送數(shù)組名字因數(shù)組名字表示地址,我們傳送數(shù)組名字 line,并傳送一個規(guī)定數(shù)組大小的整數(shù),并傳送一個規(guī)定數(shù)組大小的整數(shù) 100, 如果在函數(shù)如果在函數(shù) getline 內(nèi)改動了第一個形式參內(nèi)改動了第一個形式參數(shù)指向的變量的值,也就相應(yīng)地改動了主數(shù)指向的變量的值,也就相應(yīng)地改動了主調(diào)函數(shù)中的數(shù)組的值。調(diào)函數(shù)中的數(shù)組的值。B.3 指向指針的指針作參數(shù)指向指針的指針作參數(shù) 有時需修改用地址傳送去的實在參數(shù),如調(diào)用一個函數(shù),有時需修改用地址傳

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論