C語言chap8(指針).ppt_第1頁
C語言chap8(指針).ppt_第2頁
C語言chap8(指針).ppt_第3頁
C語言chap8(指針).ppt_第4頁
C語言chap8(指針).ppt_第5頁
已閱讀5頁,還剩43頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第8章 指針,8.1 指針概念,指針是C的一個(gè)重要概念。其特點(diǎn)是: 能有效地表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu);能動態(tài)地分配內(nèi)存,直接處理內(nèi)存地址;能方便、有效地使用字符串和數(shù)組;能在調(diào)用函數(shù)后獲得多個(gè)值。 C中定義的變量,在編譯時(shí)按變量的類型來分配一定長度的內(nèi)存單元。在運(yùn)行時(shí),根據(jù)變量名與地址的對應(yīng)關(guān)系,相應(yīng)地存取變量的數(shù)據(jù)。這種按變量地址存取變量值的方法稱為“直接訪問”方式。 如果變量的地址也存放在某一個(gè)內(nèi)存單元,則存取方式為先找到存放變量的地址單元,再取變量的值,這種方式稱為“間接訪問”方式。如: 將變量 i 的地址保存到p中; 依據(jù)p當(dāng)然可以訪問到i,8.1.1. 變量的指針和指向變量的指針變量,變量的指針就是變量的地址,即p的值。也就是說, 指針變量的值就是該指針變量所指變量的內(nèi)存首地址。 在p的前面加上一個(gè)“ * ”(稱其為“間接引用運(yùn)算符”),即*p就表示指針變量p所指向的變量。 從右圖可知 : *p也是一個(gè)變量,且與變量 i 是同一回事。 i = 3;與p= 是同一回事 / 將3賦給指針變量p所指向的變量 /,8.1.2指針變量的定義,定義形式: 類型標(biāo)識符 *標(biāo)識符; 指針變量必須定義指針?biāo)笖?shù)據(jù) 類型。如: int i, j; int *p1,*p2; p1= 非法。,與指針有關(guān)的運(yùn)算符: 是將變量j的值賦給目標(biāo)變量*p(即i)。 * 運(yùn)算和& 運(yùn)算互為逆運(yùn)算。 &(*p)的結(jié)果為p,即變量*p的地址; *(&i)表示訪問變量 i 的地址,其結(jié)果就是 i 本身。 &p為指針變量p的地址。,8.1.3 指針變量的引用,運(yùn)行結(jié)果: 100, 10 100, 10,例8.1 main( ) int a,b; int *p1,*p2; a=100; b=10; p1= / *p1和*p2就是變量a和b / , 若先執(zhí)行p1= 是什么意思? 這里“&”和“*”的優(yōu)先級相同,但按“自右至左”結(jié)合, 即&*p1與&a相同。, 若先執(zhí)行p1= 則 *&a和*p1的作用相同。即:*&a與a是等價(jià)的。,說明:,而p2= 的作用是將&a 賦給p2。, (*p1)+ 等價(jià)于a+。,注意:括號是必須的,否則就成為*(p1+)。這時(shí)先按p1的原值進(jìn)行 * 運(yùn)算得到a的值。然后使p1的值改變,則p1不再指向a了。,注意:此例中a和b并未交換,而p1和p2的值改變。,例8.2 main( ) int *p1,*p2,*p,a,b; scanf(“%d,%d”, ,運(yùn)行情況: 5,9 a=5,b=9 max=9,min=5,8.2 指針的運(yùn)算 8.2.1 指針的算術(shù)運(yùn)算 主要為 + - + - P+ 、 p 分別表示向后、向前移一個(gè)單元。 P+n、p-n 分別表示向后、向前移n個(gè)單元。 8.2.2 指針的關(guān)系運(yùn)算 主要為 = 、 !=兩種。 當(dāng)兩個(gè)指針p1與p2指向同一地址時(shí),p1=p2為真, 當(dāng)兩個(gè)指針p1與p2不指向同一地址時(shí),p1!=p2為真。,8.3.1 指向一維數(shù)組的指針 例:int a10, *p; p= 則*(p+i)或*(a+i)就是p+i或a+i所指向的數(shù)組元素,即ai。也就是說 *(p+i) = *(a+i) = ai。 指向數(shù)組的指針變量可以帶下標(biāo),如:pi 與 *( p+i)是等價(jià)的。,8.3 指針與數(shù)組,也可寫成如下: main( ) int a10, *p=a , i ; for ( i=0; i10; i+) scanf(“%d”,p+); printf(“n”); p=a; / 此語句必不可少 / for ( i=0; i10; i+, p+) printf(“%d”,*p); ,例8.3 輸出有10個(gè)元素的整型數(shù)組a的元素值。 main( ) int a10, *p, i ; for (i=0; i10; i+) scanf(“%d”, , 要注意指針變量的運(yùn)算。如果p指向數(shù)組a (即p=a),則: p+(或p+=1)表示p指向下一個(gè)元素;*p表示取得當(dāng)前所指元素之值。 *p+等價(jià)于*(p+),相當(dāng)于ai+,表示先*p,再p+1p。 *p 等價(jià)于*(p ),相當(dāng)于ai ,表示先*p,再p1p。 *(+p) 相當(dāng)于a+i,表示p+1p,再*p。 *( p) 相當(dāng)于a i,表示p1p,再*p。 (*p)+ 表示p所指之元素的值加1,不是指針值加1。即ai+1。, 要注意指向數(shù)組的指針變量的當(dāng)前值,因?yàn)橹羔樋梢灾赶驍?shù)組最后一個(gè)元素以后的內(nèi)存單元。,設(shè)二維數(shù)組a定義如下: static int a34=1,3,5,7,9,11,13,15,17,19,21,23; a 代表整個(gè)二維數(shù)組的首地址,也就是0行的首地址。a+1、a+2分別代表1行和2行的首地址。同樣,a0或&a00、a1或&a10、a2或&a20也分別代表0行、1行、2行的首地址。 a0等價(jià)于*(a+0)、a1等價(jià)于*(a+1), ,ai等價(jià)于*(a+i)。因此,a0+1和*(a+0)+1的值都是&a01;a1+2和*(a+1)+2的值為&a12。 *(a+1)+2不能寫成*(a+1+2),否則就變成*(a+3), 即a3。 因a0+1和*(a+0)+1是a01的地址,則*(a0+1)就是a01的值, 同理,*(*(a+0)+1)或*(*a+1)是a01的值,*(a i + j)或*(*(a+i)+j )是a i j的值。,8.3.2 指向多維數(shù)組的指針,務(wù)必記?。?( a + i ) 和 a i 是等價(jià)的。, 如果 a 是一維數(shù)組名,則a i 代表第 i+1個(gè)元素所占的內(nèi)存單元。但如果a是二維數(shù)組,則a i 代表一維數(shù)組名,a i 本身是不占用內(nèi)存單元的, 也不存放元素值,而只是一個(gè)地址。,a、a+i、a i 、*(a+i)、*(a+i)+j、a i +j都是地址,而*(a i +j)、*(*(a+i)+j)是二維數(shù)組元素a i j的值。, 在二維數(shù)組中&a i 并不是a i 單元的物理地址,但能得到i行的首地址。雖然&a i 和a i 的值是相同,但含義不同。&a i 或a+i表示行,而a i 或*(a+i)表示列。, 在一維數(shù)組中a+i所指的是第i個(gè)數(shù)組元素的存儲單元;在二維數(shù)組中,a+i=a i =*(a+i)=&a i =&a i 0,都表示 i 行0列元素的地址。,例8.4 輸出二維數(shù)組中任一行任一列的元素。 main( ) static int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4, i, j; p=a; scanf(“i=%d, j=%d”, ,運(yùn)行情況: i=1, j=2 /* 注意這里的輸入格式 */ a1,2=13,程序中的“int (*p)4”表示 p 是一個(gè)指向包含4個(gè)元素的一維數(shù)組的指針變量,即p是一個(gè)行指針,指向一維數(shù)組的首地址。由于運(yùn)算符優(yōu)先級的關(guān)系,這里的(*p)4不能寫成*p4。,一、 字符串的表示形式 用字符數(shù)組實(shí)現(xiàn) static char str =“I love China !”; stri表示字符數(shù)組中的第i+1個(gè)字符。如: str8為字符h 用字符指針實(shí)現(xiàn) char *a=“I love China!”; 盡管沒有定義為字符數(shù)組,但實(shí)際在內(nèi)存開辟了一個(gè)字符數(shù)組用來存放字符串常量。同樣,a8為字符h。 注意: a不是字符串變量,只是將“I love China!”的首地址賦給指針變量a 。,8.3.3 字符串的指針,二、 字符串指針作函數(shù)參數(shù),可以用地址傳遞的方式,即用字符數(shù)組名作參數(shù)或用指向字符串的指針變量作參數(shù),將一個(gè)字符串從一個(gè)函數(shù)傳遞到另一個(gè)函數(shù)。,例8.5 用函數(shù)調(diào)用實(shí)現(xiàn)字符串的復(fù)制。, 用字符數(shù)組作參數(shù),void copy_string( from , to ) char from , to ; int i = 0 ; while ( fromi != 0 ) toi = fromi ; i + + ; toi = 0 ; main( ) char a = “I am a teacher.” ; char b = “you are a student.” ; copy_string( a , b) ; printf( “string_a = %snstring_b = %sn”,a,b); ,運(yùn)行結(jié)果: string_a = I am a teacher. string_b = I am a teacher., 形參用字符指針變量,void copy_string(from , to) char *from , *to ; for ( ; *from != 0; from+; to+) *to = *from ; *to = 0; main( ) char *a= “I am a teacher.”; char *b= “you are a student.”; copy_string(a,b); printf( “string_a = %snstring_b = %sn”,a,b) ; ,用字符數(shù)組和字符指針變量都能實(shí)現(xiàn)字符串的存儲和運(yùn)算,但二者之間是有區(qū)別的,不要混為一談,必須注意以下幾點(diǎn): 字符數(shù)組由若干個(gè)元素組成,每個(gè)元素可存放1個(gè)字符,而字符指針變量存放的是字符串的首地址,絕不是將字符串存放到字符指針變量中。 對字符數(shù)組賦初值要用static存儲類別,如: static str =“I love China!”; 而對字符指針變量不必加 static,如: char *a=“I love China!”; 這是因?yàn)樗皇菍χ羔樧兞砍跏蓟皇菍?shù)組初始化。 對字符數(shù)組只能對各個(gè)元素賦值,下列方式是錯(cuò)誤的 char str15; str=“I love China!”;,三、 字符指針變量與字符數(shù)組, 對字符指針變量賦初值時(shí):,char *a=“I love China!”; 等價(jià)于: char *a; a=“I love China!”;,而對于字符指針變量,可采用如下方法: char *a; a = “I love China!”; 這里賦給a的是字符串的首地址,而不是字符串。,即數(shù)組可以在變量定義時(shí)整體賦初值,但不能在賦值語句中整體賦值。,注意:對數(shù)組初始化時(shí): static char str14=“I love China!”; 不等價(jià)于: char str14; str =“I love China!”;,char str14; scanf(“%s”,str); 是可以的。但如果寫成如下形式: char *a; scanf(“%s”,a); 是非常危險(xiǎn)的。因?yàn)橹羔樧兞繘]有確定的地址而指向程序區(qū)或其它數(shù)據(jù)區(qū),從而會造成系統(tǒng)“沖突”。應(yīng)當(dāng)寫成如下形式: char *a, str10; a=str; scanf(“%s”,a);, 數(shù)組在編譯時(shí)被分配內(nèi)存單元,有確定的地址。而指針變量必須賦給一個(gè)確定的地址值,否則,在程序運(yùn)行時(shí)會發(fā)生意想不到的后果。如:,main( ) char *a=“I love China!”; a=a+7; printf(“%s”,a); 運(yùn)行結(jié)果如下: China! 下面的寫法是錯(cuò)誤的: char str =“I love China!”; str=str +7; printf(“%s”,str); 若定義一個(gè)指針變量使它指向一個(gè)字符串后,可以用下標(biāo)形式引用指針變量所指字符串中的字符。, 指針變量的地址值是可以改變的,而數(shù)組名的地址值是不能改變的。如:,例8.6 main( ) char *a=“I love China.”; int i=5; printf(“%cn”,ai); for (i=7; ai!=0; i+) printf(“%c”,ai); ,運(yùn)行結(jié)果如下: e China., 可以用指針變量指向一個(gè)格式字符串來代替printf函數(shù)中的格式字符串。也可以在定義字符數(shù)組賦初值時(shí)賦予一個(gè)格式字符串代替printf函數(shù)中的格式字符串。如: char *format; format=“a=%d, b=%f n”; printf(format, a, b); 它相當(dāng)于: printf(“a=%d, b=%f n”, a, b);,例8.7 順讀和倒讀都一樣的字符串稱為“回文”,如:LEVEL。試編寫一個(gè)判斷輸入的字符串是否為回文的程序。 #include “stdio.h” #include “string.h” main( ) char s81, *pi, *pj; int i, j, n; gets(s); n=strlen(s); pi=s; pj=s+n-1; while (*pi= ) pi+; / 跳過輸入時(shí)的前導(dǎo)空格 / while (*pj= ) pj-; / 跳過輸入時(shí)的尾隨空格 / while (pipj) ,8.3.4 指針數(shù)組,char *p ; int i; for (i=0; i5; i+ +) p= name+i; printf(“%sn”,*p); , 指針數(shù)組的概念,指針數(shù)組的定義形式: 類型標(biāo)識符 *數(shù)組名數(shù)組長度,例如:int *p4; 定義了有4個(gè)元素的指針數(shù)組,每個(gè)數(shù)組元素都可以指向一個(gè)整型變量。,例8.8 main( ) static char *name =“Follow me”, “BASIC”, “Great Wall”, “FORTRAN”, “Computer design”;,指向指針的指針,指針變量作為函數(shù)參數(shù)的作用是將一個(gè)變量的地址傳送至另一個(gè)函數(shù)中 例8.9,8.4 指針變量作為函數(shù)參數(shù),用指針變量作參數(shù)調(diào)用函數(shù)能獲得多個(gè)值。此例中a和b的值交換,而s1和s2的值不變。,8.5 返回指針值的函數(shù) 返回指針值的函數(shù)也稱為指針函數(shù)。調(diào)用指針函數(shù)后能得到一個(gè)指向指定類型數(shù)據(jù)的指針(地址)。指針函數(shù)的定義形式如下: 類型標(biāo)識符 *函數(shù)名(參數(shù)表) 例如:int *fa(x, y); 定義了一個(gè)指針函數(shù) fa 。 x , y 為函數(shù) fa 的形參。,例:8e_1 在字符串中尋找關(guān)鍵字(演示) #include char *search(char *tagstr, char *c) char *p=tagstr; while(*p!=0) if (*p=*c) return p; p+; return NULL; ,main() char *string=“I am a student“,c; printf(“Please enter the character:“); scanf(“%c“, ,8.6 指向函數(shù)的指針,1.函數(shù)指針變量的定義,例:int (p) ( );,表示p為一個(gè)函數(shù)指針變量,用于存放一個(gè)函數(shù)的入口地址,但該函數(shù)的返回值必須為int型。,2.給函數(shù)指針變量賦值,3.通過函數(shù)指針變量調(diào)用函數(shù)的方法,它不是實(shí)參,不是調(diào)用,而是將入口地址賦給該變量。,函數(shù)指針變量函數(shù)名;,(函數(shù)指針變量名) (實(shí)參表列);,注意指針函數(shù)與指向函數(shù)的指針變量之間的區(qū)別。 int (*a)( ); 定義a為指向函數(shù)的指針變量。 例如: int *a(x,y); 定義a為整型指針函數(shù)。,一、 用函數(shù)指針變量調(diào)用函數(shù),例8.10 求a、b 兩數(shù)中較大者。 main( ) int max( ); int (*p)( ); / 說明p是指向函數(shù)的指針變量 / int a, b, c; p=max; scanf(“%d, %d”, ,二、函數(shù)指針變量作為函數(shù)參數(shù),意義:當(dāng)一個(gè)函數(shù)被調(diào)用后,執(zhí)行過程中可以根據(jù)實(shí)參的函數(shù)名來調(diào)用不同的函數(shù)。,前面介紹過:簡單變量、數(shù)組名、指針變量均可作為函數(shù)的參數(shù)。,可以用函數(shù)指針變量作為函數(shù)的參數(shù)。,例:sub (x1, x2) int (x1 )( ), (x2 )( ); int a, b, i, j; a=(x1) (i); b=(x2) (i, j) ,于是,可用 sub(f1, f2)或sub(f3, f4)調(diào)用sub,表示執(zhí)行sub時(shí),根據(jù)實(shí)參傳遞過來的函數(shù)入口地址而調(diào)用f1, f2或f3, f4。,例8e_2. 設(shè)計(jì)一個(gè)函數(shù)process, 每次實(shí)現(xiàn)不同的功能,當(dāng)用不同的函數(shù)名作實(shí)參調(diào)用process時(shí),process再去調(diào)用相應(yīng)的函數(shù)。,程序如下(演示) #include main ( ) int max( ), min( ), add( ); int a, b; printf(“enter a and b:“); scanf(“%d, %d“, ,printf(“max=“); process(a, b, max); printf(“min=“); process(a, b, min); printf(“sum=“); process(a, b, add); ,每次調(diào)用同一個(gè) 函數(shù)名process 完成了不同功能,max(x, y) int x, y; int z; if (xy) z=x; else z=y; return(z); ,min(x, y) int x, y; int z; if (xy) z=x; else z=y; return(z); ,add(x, y) int x, y; int z; z=x+y; return(z); ,process (x, y, fun) int x, y; int (* fun) ( ); int result; result=(*fun) (x,y); printf(“%dn“, result); ,注:當(dāng)用函數(shù)名作參數(shù)時(shí),不論函數(shù)返值類型如何均應(yīng)作說明,以與變量名相區(qū)別。,enter a and b:2, 6 max=6 min=2 sum=8,運(yùn)行情況如下:,那么它的實(shí)參從何而來?實(shí)參代表的含義是什么? 觀察DOS系統(tǒng)下的一種命令: c: copy FILE1.C FILE2.C,main( )既可為無參函數(shù),也可為有參函數(shù),有參函數(shù)形式: main (int argc, char *argv , char * env ) ,8.7 main函數(shù)參數(shù),其中:copy為命令 , FILE1.C 和FILE2.C為其參數(shù)。,對于一個(gè)在DOS下運(yùn)行的C程序,也可以給一些參數(shù):,當(dāng)以這種方式運(yùn)行C程序,則argcn, argv為指針數(shù)組,每一個(gè)元素指向包含命令在內(nèi)的n個(gè)字符串。,即: argv0“pop“ argv1 “參數(shù)1“ argvn 1 “參數(shù)n 1 “,如:c: pop 參數(shù)1 參數(shù)2 參數(shù)n1,#include main (argc, argv) int argc; char argv ; printf(“argc=%d“, argc); while (argc1) +argv; printf(“%sn“, argv); argc; ,例:8e_3編寫main( )函數(shù),將后面的參數(shù)輸出(演示),file1 China Beijing Changsha argc=4 China Beijing Changsha,上述文件設(shè)為file1 則運(yùn)行時(shí):,指向指針數(shù)據(jù)的指針變量稱為指向指針的指針。如: char *p; *運(yùn)算符的結(jié)合性是從右至左,因此,*p相當(dāng)于*(*p)。,8.8 指向指針的指針,例8.11 main( ) static int a5=1, 3, 5, 7, 9; static int *num5= /* 此處*p改為*p行嗎?*/ ,注意:不得將第2、3行錯(cuò)寫為如下的一行: static int *num5=1,3,5,7,9;,例8.12 輸入一行字符,統(tǒ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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論