




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
模塊八指針正確而靈活地使用指針,可以表示各種數(shù)據(jù)結(jié)構(gòu),能很方便地使用數(shù)組和字符串,從而可以使程序簡潔、高效。8.1
指針的概念學(xué)習(xí)目標(biāo)1、理解指針和地址的關(guān)系;2、掌握指針的概念和作用。定義一個(gè)變量,再定義一個(gè)指針指向該變量。案例
8-11、定義如下:
charch=‘a(chǎn)’; char*p=&ch;2、語句charch=‘a(chǎn)’;表示定義了一個(gè)字符變量,變量名為ch,變量的值為字符常量‘a(chǎn)’。定義后,在編譯時(shí)系統(tǒng)會為該字符變量分配一個(gè)內(nèi)存單元,假設(shè)該內(nèi)存單元編號是2000。這里,單元編號2000就是該內(nèi)存單元的地址,就是變量ch的地址,字符常量‘a(chǎn)’就是該內(nèi)存單元的內(nèi)容,也就是變量ch的值。案例分析3、如果執(zhí)行scanf(“%c”,&ch);語句,實(shí)際上就是把鍵盤輸入的字符值(ASCII碼值)送到變量ch的地址(為2000)對應(yīng)的內(nèi)存單元中。4、前面都是通過變量名來訪問變量的內(nèi)容,也就是變量對應(yīng)的內(nèi)存單元的值,那在理解了內(nèi)存單元地址和內(nèi)容的關(guān)系之后,可不可以定義一種變量來保存內(nèi)存單元的地址,從而達(dá)到訪問內(nèi)存單元的內(nèi)容的目的呢?chp2000‘a(chǎn)’定義一種變量專門用來保存內(nèi)存單元的地址,地址稱為指針,那么這種保存地址的變量就被稱為指針變量指針的定義1、指針的概念2、地址和內(nèi)容的關(guān)系提示:1、要正確區(qū)分變量名、變量地址、變量內(nèi)容三個(gè)概念。變量名就是給變量取的名字,變量地址就是系統(tǒng)給變量分配的內(nèi)存單元的起始地址編號,變量內(nèi)容就是對應(yīng)內(nèi)存單元中存放的數(shù)據(jù)。2、指針本質(zhì)上就是所要指向數(shù)據(jù)類型的地址。指針=地址知識鏈接學(xué)習(xí)目標(biāo)1、掌握指針變量的定義和初始化;2、掌握指針變量的引用8.2指針和指針變量案例8-2定義指針變量并解釋其意義。8.2.1指針變量的定義1、定義:int*p;表示定義一個(gè)指向整型數(shù)據(jù)的指針。類型說明符int表示指針指向整型變量,(*)表示變量p是指針變量,它保存的是某個(gè)整型變量的地址(指針),p是指針變量名。2、又如:float*pointer; /*定義指針變量pointer,指向浮點(diǎn)型變量*/char*p_char; /*定義指針變量p_char,指向字符型變量*/案例分析1、指針變量的定義2、指針變量的一般格式知識鏈接案例8-3區(qū)分下列兩種指針變量初始化方法。1、int*p;p=&i;2、int*p=&i;8.2.2指針變量初始化1、定義指針變量后進(jìn)行初始化定義指針變量后再進(jìn)行初始化的一般格式是:指針變量名=&所指向的變量名案例分析ip&i2、定義的同時(shí)進(jìn)行初始化
例如:inti,j; int*p=&i,*q=&j;指針的定義案例8-4定義一個(gè)指向整型變量的指針,并進(jìn)行初始化和引用,最后輸出變量的地址和指針變量本身的值。8.2.3指針變量的引用main(){ inta,*p; /*定義整型變量a和整型指針p*/ a=117; /*給變量a賦值*/ p=&a; /*把a(bǔ)的地址保存在p中,使p指向邊變量a*/ printf("a=%d,*p=%d\n",a,*p); /*輸出a的值和p指針引用的值*/ *p=218;
printf("a=%d,*p=%d\n",a,*p); /*再次輸出a的值和p指針引用的值*/ printf("Theaddressofais:%ld\n",(long)&a); /*輸出變量a的內(nèi)存地址*/printf("Theaddressofais:%ld\n",(long)p);/*輸出變量a的內(nèi)存地址*/}案例程序運(yùn)行程序,結(jié)果是:
a=117,*p=117 a=218,*p=218 Theaddressofais:1693056984 Theaddressofais:1693056984用變量名訪問和用指針變量訪問的比較charch;char*p=&ch;printf(“%c”,ch);
或printf(“%c”,*p); 知識鏈接提示:注意指針的定義和引用的區(qū)別,定義時(shí)的形式包含類型說明符,比如char*p;這里的“*”表示p是一個(gè)指針變量,而引用時(shí)的形式不包含類型說明符,比如剛才printf語句中的“*p”,這里的“*”實(shí)際上是運(yùn)算符,稱為指針運(yùn)算符,它的作用相當(dāng)于引用指針?biāo)赶虻淖兞?,或者說是引用指針?biāo)赶虻牡刂房臻g的內(nèi)容。提示從鍵盤輸入兩個(gè)整數(shù),通過指針引用,把兩個(gè)數(shù)由大到小輸出到屏幕上。案例8-5main(){ inta,b; /*定義兩個(gè)整型變量*/ int*p1,*p2,*p; /*定義三個(gè)指向整型變量的指針*/ clrscr(); p1=&a; p2=&b; /*p1指向a,p2指向b*/ scanf("%d%d",p1,p2); /*輸入a和b的值*/ printf("*p1=%d,*p2=%d\n",*p1,*p2); /*輸出p1和p2所指向變量的值*/ if(a<b) { p=p1;p1=p2;p2=p; /*如果a<b,則交換指針變量p1和p2的值*/ } printf("a=%d,b=%d\n",a,b); /*輸出變量a和b的值*/ printf("*p1=%d,*p2=%d\n",*p1,*p2); /*輸出p1和p2所指向變量的值*/}案例程序運(yùn)行程序,鍵盤輸入:3849↙輸出結(jié)果是: *p1=38,*p2=49 a=38,b=49 *p1=49,*p2=38 案例分析定義三個(gè)整型變量和三個(gè)指向整型數(shù)據(jù)的指針,用指針指向三個(gè)整型變量,并按由大到小輸出三個(gè)變量的值。隨堂練習(xí)案例8-6用指針變量作為函數(shù)參數(shù)改變某個(gè)變量的值8.2.4指針變量作為函數(shù)的參數(shù)changevalue(int*pt) /*函數(shù)changevalue()的功能是改變變量a的值*/{ *pt=555; /*改變指針變量所指向內(nèi)存單元的值*/}main(){ inta=10; /*定義整型變量a并賦初值為10*/ int*p=&a; /*定義整型指針變量p并賦初值為變量a的地址*/ changevalue(p); /*調(diào)用函數(shù)用指針p作為參數(shù)*/ printf("a=%d\n",a); /*調(diào)用后輸出a的值*/}運(yùn)行程序,結(jié)果是:a=555案例程序案例分析用變量名作為函數(shù)參數(shù)改變某個(gè)變量的值案例8-7voidchangevalue(intb) /*函數(shù)changevalue()的功能是改變變量a的值*/{ printf("b=%d\n",b); /*輸出形參b的值*/ b=555; /*變量b的值改為555*/}main(){ inta=10; /*定義整型變量a并賦初值為10*/ changevalue(a); /*調(diào)用函數(shù)用變量a作為參數(shù)*/ printf("a=%d\n",a); /*調(diào)用后輸出a的值*/}案例程序運(yùn)行程序,結(jié)果是:
b=10 a=10案例分析定義一個(gè)函數(shù),實(shí)現(xiàn)兩個(gè)整型變量值的交換案例8-8voidswap(int*pa,int*pb) /*函數(shù)swap(),用于交換變量a和b的值*/{ intmed; /*定義整型變量med,用于做交換的中間存儲*/ med=*pa; /*把變量a的值先保存在臨時(shí)輔助(中間存儲)變量med中*/ *pa=*pb; /*交換pa和pb所指向變量的值*/ *pb=med;} 案例程序main(){ inta=11,b=22; /*定義兩個(gè)整型變量a和b*/ int*p1,*p2; /*定義兩個(gè)指針變量p1和p2*/ p1=&a;p2=&b; /*p1和p2初始化為變量a和b的地址*/ swap(p1,p2); /*調(diào)用swap,實(shí)現(xiàn)變量a和b的值的互換,用指針作為實(shí)參*/ printf("a=%d,b=%d\n",a,b); /*輸出a和b的值*/ printf("*p1=%d,*p2=%d\n",*p1,*p2); /*輸出p1和p2所指向變量的值*/}運(yùn)行程序,結(jié)果是:
a=22,b=11 *p1=22,*p2=11 案例分析如果把swap()函數(shù)改成下面的代碼,請考慮能否實(shí)現(xiàn)a和b互換。
voidswap(int*pa,int*pb) { int*temp; temp=pa; pa=pb; pb=temp; }1、編程從鍵盤輸入兩個(gè)數(shù),用函數(shù)調(diào)用的方式(用指針作為函數(shù)參數(shù)),實(shí)現(xiàn)兩個(gè)數(shù)由大到小排序。2、編程從鍵盤輸入三個(gè)數(shù),用函數(shù)嵌套調(diào)用的方式,先調(diào)用三個(gè)數(shù)交換的函數(shù),再在三個(gè)數(shù)交換的函數(shù)中調(diào)用兩個(gè)數(shù)交換的函數(shù)(調(diào)用過程中都用指針作為函數(shù)參數(shù))。 隨堂練習(xí)函數(shù)的參數(shù)傳遞,有兩種方式,一種是傳值方式,另一種是傳址方式。對于變量來說,傳值方式就是把變量的值作為參數(shù)傳遞,比如用變量名作為參數(shù)就是這種方式;傳址方式就是把變量的地址作為參數(shù)傳遞,比如用指針指向某一變量,然后用指針作為參數(shù),另外,用數(shù)組名作為參數(shù)也是傳址方式。知識鏈接學(xué)習(xí)目標(biāo)掌握指向數(shù)組的指針以及指針和數(shù)組名的關(guān)系。掌握指向數(shù)組元素的指針以及通過指針引用數(shù)組元素。指針和數(shù)組之間存在特殊的關(guān)系。一個(gè)變量有一個(gè)地址,一個(gè)數(shù)組包含若干個(gè)元素,每個(gè)數(shù)組元素都在內(nèi)存中占有相應(yīng)的內(nèi)存單元,都有相應(yīng)的地址。因此指針變量可以指向數(shù)組,也可以指向數(shù)組元素。所謂數(shù)組的指針就是數(shù)組的起始地址,數(shù)組元素的指針就是數(shù)組元素的地址。我們把指向數(shù)組的指針變量稱為“指向數(shù)組的指針”,把指向數(shù)組元素的指針變量稱為“指向數(shù)組元素的指針”。8.3指針與數(shù)組案例8-9定義一個(gè)數(shù)組,然后定義一個(gè)指針指向該數(shù)組。8.3.1指向數(shù)組的指針1、一個(gè)數(shù)組是由連續(xù)的一塊內(nèi)存單元組成的。數(shù)組名就是這塊連續(xù)內(nèi)存單元的首地址。數(shù)組的元素按順序存儲在內(nèi)存單元中,它的第一個(gè)元素(如array[0])存儲在首地址對應(yīng)的內(nèi)存單元中,后面的數(shù)組元素(下標(biāo)大于0)存儲在后續(xù)的內(nèi)存單元中。例如定義一個(gè)整型數(shù)組:
intarray[5];案例分析1、一個(gè)數(shù)組是由連續(xù)的一塊內(nèi)存單元組成的。數(shù)組名就是這塊連續(xù)內(nèi)存單元的首地址。數(shù)組的元素按順序存儲在內(nèi)存單元中,它的第一個(gè)元素(如array[0])存儲在首地址對應(yīng)的內(nèi)存單元中,后面的數(shù)組元素(下標(biāo)大于0)存儲在后續(xù)的內(nèi)存單元中。例如定義一個(gè)整型數(shù)組:
intarray[5];假定array數(shù)組的起始地址是1000,存放形式如圖提問:請考慮下面的關(guān)系是否成立?(1)array==1000(2)&array[0]==1000(3)array==&a[0](4)&array[1]==10022、在清楚了數(shù)組在內(nèi)存中的存儲形式以后,下一步我們就可以定義指針來指向數(shù)組了。在前面已經(jīng)定義了數(shù)組array[],再定義指針p指向數(shù)組array。
intarray[5]; int*p; /*定義p為指向整型變量的指針*/這里定義指針p為整型的原因就是因?yàn)閿?shù)組array是int型,所以p也應(yīng)為指向int型的指針變量。為了使指針p指向數(shù)組array,需要把數(shù)組的起始地址賦給指針變量p,以下兩種方法都是等價(jià)的。(1)p=&array[0];(2)p=array;也可以在定義的同時(shí)賦初值給指針變量p:(1)int*p=&array[0]; /*求得第一個(gè)元素array[0]的地址賦給p*/(2)int*p=array; /*數(shù)組名a相當(dāng)于數(shù)組的首地址,賦給p*/提示:(1)指針變量經(jīng)過定義和賦初值以后,由于p的初值被賦為數(shù)組的起始地址,所以指針變量p、數(shù)組名array、&array[0]三者的值都是1000,如圖8-15所示。指針變量p、數(shù)組名array、&array[0]均指向同一單元,它們是數(shù)組的首地址,也就是數(shù)組的第一個(gè)元素array[0]的地址。(2)注意數(shù)組名和數(shù)組元素的地址是常量,而指針變量是變量。1、指針變量指向數(shù)組首地址的方式如下:方式1:類型說明符*指針變量=數(shù)組名(或&數(shù)組名[0]); /*在定義指針的同時(shí)賦初值*/方式2:指針變量=數(shù)組名(或&數(shù)組名[0]); /*在定義了指針變量后*/2、指針變量指向數(shù)組某個(gè)元素的方式如下:方式1:類型說明符*指針變量=&數(shù)組名[下標(biāo)]; /*在定義指針的同時(shí)賦初值*/方式2:指針變量=&數(shù)組名[下標(biāo)]; /*在定義了指針變量后*/知識鏈接有兩種方法可用于引用一個(gè)數(shù)組元素,即下標(biāo)法和指針法。案例8-10定義數(shù)組并給數(shù)組賦初值,用下標(biāo)法引用數(shù)組的元素并輸出數(shù)值中各元素的值。8.3.2通過指針引用數(shù)組元素main(){intarray[5]={1,2,3,4,5}; /*定義循環(huán)變量i*/inti; /*定義數(shù)組array并初始化*/for(i=0;i<5;i++) /*用循環(huán)方式輸出數(shù)組各元素的值*/printf(“array[%d]=%d”,i,array[i]);/*用下標(biāo)法引用數(shù)組的元素*/}運(yùn)行程序,結(jié)果是:
array[0]=1array[1]=2array[2]=3array[3]=4array[4]=5案例程序定義數(shù)組并給數(shù)組賦初值,用指針法引用數(shù)組的元素并輸出數(shù)值中各元素的值。案例8-11main(){inti; /*定義循環(huán)變量i*/intarray[5]={1,2,3,4,5}; /*定義數(shù)組array并初始化*/int*p=array; /*定義指針p并指向數(shù)組的起始地址*/for(i=0;i<5;i++) /*用循環(huán)方式輸出數(shù)組各元素的值*/printf("array[%d]=%d",i,*(p+i)); /**(p+i)就是用指針引用數(shù)組元素*/}運(yùn)行程序,結(jié)果同上一個(gè)案例一樣。 案例程序1、p指向了數(shù)組array的首地址后,p就指向了數(shù)組的第一個(gè)元素array[0],那么p+1就表示指向數(shù)組的下一個(gè)元素即第二個(gè)元素array[1,以此類推。2、既然p+i表示指向數(shù)組中的第i+1個(gè)元素,即p+i表示第i+1個(gè)元素的地址,則第i+1個(gè)元素可以表示為*(p+i)。如*p表示第一個(gè)元素array[0],*(p+1)表示第二個(gè)元素array[1]。3、程序中for循環(huán)循環(huán)五次,每次輸出*(p+i)的值,分別是輸出array[0]、array[1]、array[2]、array[3]、array[4]的值。4、當(dāng)指針指向數(shù)組的首地址后,對下標(biāo)為i的數(shù)組元素的引用有下面四種方法:(1)*(指針變量+i)(2)*(數(shù)組名+i)(3)指針變量[i](4)數(shù)組名[i] 案例分析提示:1、數(shù)組array中的下標(biāo)為i(即第i+1個(gè))的元素的地址有如下幾個(gè)表示形式:p+i、array+i、&p[i]。這里假定p指向數(shù)組的首地址。2、數(shù)組array中的下標(biāo)為i(即第i+1個(gè))的元素有如下幾個(gè)表示形式:p[i]、array[i]、*(p+i)、*(array+i)。引用數(shù)組元素可以用下標(biāo)法,即通過表示某一個(gè)數(shù)組元素在數(shù)組中有序排列位置的下標(biāo)去訪問該數(shù)組元素,如array[5];也可以用指針法,即通過指向數(shù)組元素的指針去訪問它。也就是說任何能由數(shù)組下標(biāo)完成的操作也都可用指針來實(shí)現(xiàn),而且在程序中使用指針不僅使代碼更緊湊、靈活,而且還可使目標(biāo)代碼占用內(nèi)存少、運(yùn)行速度快。提問:占用內(nèi)存少、運(yùn)行速度快?知識鏈接編程實(shí)現(xiàn)通過指針引用、數(shù)組名及下標(biāo)引用等方法引用數(shù)組元素案例8-12main(){intarr[5],i,*p; /*定義數(shù)組arr,循環(huán)變量i和指針p*/p=arr; /*p指向數(shù)組的首地址*/for(i=0;i<5;i++)scanf("%d",p+i); /*從鍵盤輸入數(shù)據(jù)賦值給數(shù)組的各個(gè)元素*/for(i=0;i<5;i++)printf("arr[%d]\t=%d\t",i,arr[i]); /*下標(biāo)法*/ 案例程序
printf("\n");for(;p<arr+5;p++)printf("*p\t=%d\t",*p); /*指針法*/printf("\n");for(i=0;i<5;i++)printf("*(arr+%d)\t=%d\t",i,*(arr+i)); /*數(shù)組名變量表示法*/
printf("\n");for(p=arr,i=0;i<5;i++)printf("*(p+%d)\t=%d\t",i,*(p+i)); /*指針變量表示法*/printf("\n");for(i=0;i<5;i++)printf("p[%d]\t=%d\t",i,p[i]); /*指針下標(biāo)表示法*/}2、語句scanf(“%d”,p+i);也可以改成scanf(“%d”,arr+i);或scanf(“%d”,&arr[i]);3、各個(gè)輸出語句分別采用不同的引用方法,arr[i]是使用下標(biāo)法,即數(shù)組名[i]方法;*p是使每次循環(huán)指針變量做加1操作指向下一個(gè)數(shù)組元素的方法;*(arr+i)是使用*(數(shù)組名+i)的方法;*(p+i)是使用*(指針變量+i)的方法;p[i]是使用指針變量[i]的方法。案例分析1、利用指針變量引用數(shù)組各個(gè)元素并輸出。2、從鍵盤輸入5門課程的成績,利用函數(shù)求平均成績(用指針作為函數(shù)參數(shù))。3、編程將0到9存儲到一個(gè)一維數(shù)組中并輸出,代碼如下:
main() { int*p,i,a[10]; p=a; for(i=0;i<10;i++,p++) *p=i; for(i=0;i<10;i++,p++) printf(“a[%d]=%d\n”,i,*p); }上機(jī)調(diào)試該程序,并找出程序的錯誤。隨堂練習(xí)提示:指針p是變量,在本例中它的值是不斷改變的,在執(zhí)行第二個(gè)for循環(huán)時(shí),指針已經(jīng)指向了哪里呢?案例8-13已知一個(gè)一維數(shù)組a[10],求其中的最大數(shù)和最小數(shù)并輸出。8.3.3數(shù)組名與指針變量作為函數(shù)參數(shù)intmax,min; /*定義變量max和min保存最大和最小數(shù)*/voidmax_min(intarray[],int);main(){inti,a[10];printf("Pleaseinput10numbers:");for(i=0;i<10;i++)scanf("%d",a+i); /*輸入十個(gè)數(shù)*/max_min(a,10); /*調(diào)用函數(shù),數(shù)組名為實(shí)參*/printf("\nmax=%d,min=%d\n",max,min);} 案例程序voidmax_min(intarray[],intn) /*形參array為數(shù)組名*/{int*p;max=min=*array; /*假設(shè)第一個(gè)數(shù)為最大最小*/for(p=array+1;p<array+n;p++) /*循環(huán)與其它數(shù)比較*/if(*p>max)max=*p; /*改變最大最小變量的值*/elseif(*p<min)min=*p;}運(yùn)行程序,從鍵盤輸入五個(gè)整數(shù):67891012345↙結(jié)果是:
Pleaseinput10numbers:67891012345 max=10,min=11、定義變量max和min用來保存最大數(shù)和最小數(shù),而且為全局變量,所以在各個(gè)函數(shù)中均可訪問引用。2、輸入語句scanf(“%d”,a+i);靈活的運(yùn)用了數(shù)組名。3、語句max_min(a,10); a作為數(shù)組名作為函數(shù)的參數(shù),將a數(shù)組的首地址傳遞給形參array。4、函數(shù)max_min()中的語句max=min=*array;中的array是形參數(shù)組名,它接收實(shí)參數(shù)組a的首地址,*array相當(dāng)于引用對應(yīng)地址單元的內(nèi)容,也就是數(shù)組的第一個(gè)元素,該語句等價(jià)于max=min=array[0]。5、在執(zhí)行函數(shù)max_min()中的for循環(huán)時(shí),p的初值為array+1,也就是p指向array[1](即a[1])。以后每次執(zhí)行p++,使p指向下一個(gè)元素。案例分析1、用數(shù)組名作為函數(shù)參數(shù),在函數(shù)調(diào)用時(shí),是把實(shí)參數(shù)組的首地址傳遞給形參數(shù)組,使得兩個(gè)數(shù)組共同占用同一段內(nèi)存空間,這樣形參數(shù)組中的元素值如果發(fā)生變化就會使實(shí)參數(shù)組的元素值也同時(shí)發(fā)生變化。數(shù)組名代表的是數(shù)組的首地址,也是第一個(gè)元素的地址。在實(shí)際應(yīng)用中,既可以用數(shù)組名作為函數(shù)參數(shù),也可以用指向數(shù)組的指針變量作為函數(shù)參數(shù),在函數(shù)調(diào)用時(shí),傳遞的都是數(shù)組的起始地址。知識鏈接2、歸納起來,如果有一個(gè)實(shí)參數(shù)組,想在函數(shù)中對此數(shù)組進(jìn)行訪問,比如查詢、修改該數(shù)組元素的值等,一般就采用傳址方式,也就是傳遞數(shù)組的首地址,形參接收數(shù)組的首地址后,也就和實(shí)參一樣,共同占用相同的內(nèi)存單元,對形參數(shù)組的改變,也就相應(yīng)地改變了實(shí)參數(shù)組。這種傳遞數(shù)組的首地址的方式有以下四種。知識鏈接(1)形參和實(shí)參都用數(shù)組名。例如:main(){ inta[5];
…… f(a);}f(intb[]){
……}(2)實(shí)參用數(shù)組名,形參用指針變量。例如:main(){ inta[5];
…… f(a);}f(int*pf){
……}(3)實(shí)參、形參都用指針變量。例如:main(){ inta[5],*p; p=a;
…… f(p);}f(int*pf){
……}(4)實(shí)參為指針變量,形參為數(shù)組名。例如:main(){ inta[5],*p; p=a;
…… f(p); }f(intb[]) {
…… }定義一個(gè)有11個(gè)元素的數(shù)組,其中前10個(gè)元素為10個(gè)整數(shù),求該數(shù)組前n個(gè)元素的和。要求:1、n的值由鍵盤輸入,輸入值如果大于10則提示重新輸入。2、采用上面介紹的四種參數(shù)傳遞方式,在函數(shù)中求和,求得的結(jié)果保存在數(shù)組的最后一個(gè)元素中。3、在主函數(shù)中輸出求得的和。隨堂練習(xí)學(xué)習(xí)目標(biāo)掌握指針指向字符串的方法;掌握使用指針處理字符串。指針可以指向數(shù)組,那么指針是否可以指向字符串呢?實(shí)際上,指針是非常靈活的,它可以指向任何數(shù)據(jù)類型。如果需要指針指向某數(shù)據(jù)類型,只需要該數(shù)據(jù)類型的變量或常量的起始地址賦值給指針就可以了。字符串在C語言中是用一維數(shù)組來表示的,也是數(shù)組的一種類型。只不過該數(shù)組的每個(gè)元素是字符罷了,所以指針當(dāng)然可以指向字符串。既然指針可以指向字符串,那么就可以通過指針來實(shí)現(xiàn)對字符串的操作。8.4指針與字符串案例8-14用指針指向字符串常量并輸出字符串。案例程序#include<stdio.h>voidmain(){ char*ptr="YouandMe"; /*指針指向字符串*/ printf("%s\n",ptr); /*輸出字符串*/}運(yùn)行程序,結(jié)果是輸出字符串:YouandMe8.4.1指針指向字符串常量1、程序沒有定義字符數(shù)組,而是使用字符串常量,同字符數(shù)組一樣,字符串常量也是在內(nèi)存中分配一塊連續(xù)空間來存放字符串常量。語句char*ptr="YouandMe";在定義指針變量ptr的同時(shí),把字符串常量的首地址賦給ptr,也就是第一個(gè)字符‘Y’的地址賦給ptr,使ptr指向該字符串。使用輸出字符串格式符%s,對應(yīng)輸出ptr指向的字符串常量。這條語句還可以寫成:
char*ptr;ptr="YouandMe";案例分析2、如printf("%s\n",ptr);語句所示,輸出字符串可以使用以下格式:
printf(“%s”,指針變量);輸出格式控制符%s表示輸出一個(gè)字符串,給出指向字符串的指針變量名(這里是指向字符串的指針變量ptr),則系統(tǒng)先輸出它所輸出它所指向的第一個(gè)字符,然后自動使指針變量加1,使之指向下一個(gè)字符,輸出下一個(gè)字符,依此類推,直到遇到字符串結(jié)束標(biāo)志‘\0’,注意:字符串在內(nèi)存中都會由系統(tǒng)自動添加一個(gè)結(jié)束標(biāo)識符‘\0’。將指針指向字符串常量有兩種方法:1、在定義指針變量的同時(shí)賦初值,格式為:
char*指針變量="字符串常量";2、在定義指針變量之后,再單獨(dú)給指針變量賦初值的方法。格式為:
char*指針變量;指針變量="字符串常量";知識鏈接注意:第二種方法不可以采用下列方法,例如:
char*p; *p="YouandMe"; 想想為什么?案例8-15用戶由鍵盤輸入密碼,判斷密碼長度是否等于6,如果不等,則提示用戶重新輸入。使用指向字符數(shù)組的指針變量。8.4.2指針指向字符數(shù)組#include<stdio.h>main(){chara[10],*p;intn=0;p=a;while(1){gets(a); /*輸入一個(gè)字符串存入字符數(shù)組a中*/printf("Thestringis:%s\n",p);/*輸出從鍵盤輸入的字符串*/案例程序for(;*p!='\0';p++) /*通過for循環(huán)計(jì)算輸入字符個(gè)數(shù)*/ n++;if(n!=6) printf("Pleaseinputagain:"); /*如果輸入字符數(shù)不是6個(gè),提示重新輸入*/elsebreak; /*否則退出while循環(huán),向下執(zhí)行*/}}運(yùn)行程序,從鍵盤輸入字符串“China”,則輸出后,再提示重新輸入,再輸入字符串“flower”。運(yùn)行結(jié)果是:
China Thestringis:China Pleaseinputagain:flower Thestringis:flower1、定義數(shù)組a后,語句p=a使指針變量p保存數(shù)組a的首地址,即p指向a。2、首先調(diào)用函數(shù)gets(a)從鍵盤輸入字符串保存在字符數(shù)組a中,然后再輸出剛輸入的字符串a(chǎn)3、循環(huán)語句for(;*p!='\0';p++)n++;通過for循環(huán)計(jì)算輸入字符個(gè)數(shù)。每次統(tǒng)計(jì)一個(gè)字符后,指針p值自加1,指向下一個(gè)字符,直到遇到結(jié)束符‘\0’。4、語句if(n!=6)printf("Pleaseinputagain:");表示如果輸入字符數(shù)不是6個(gè),提示重新輸入。案例分析字符串是按照字符數(shù)組存儲的,所以對字符串中字符的引用也可以用下標(biāo)法和指針法。知識鏈接案例8-16輸入一段字符,統(tǒng)計(jì)其中所包含的單詞數(shù)量。知識鏈接#include<stdio.h>#include<string.h>intcount(char*); /*統(tǒng)計(jì)個(gè)數(shù)函數(shù)count聲明*/main(){charstr[100]; /*定義數(shù)組str來保存輸入的字符串*/intn; /*整型變量n保存單詞個(gè)數(shù)*/printf("Pleaseinputastring:\n");gets(str); /*輸入字符串,保存在字符數(shù)組str中*/n=count(str); /*調(diào)用函數(shù)count,統(tǒng)計(jì)單詞個(gè)數(shù)*/printf("Thewordsinstrare:%d\n",n); /*輸出個(gè)數(shù)*/}案例程序intcount(char*p) /*形參指針p也指向輸入的字符串*/{intnum=0,flag; /*num存儲單詞數(shù),flag為標(biāo)志變量*/flag=0; /*先把flag賦初始值為0*/while(*p!='\0') /*字符不是結(jié)束符就繼續(xù)循環(huán)*/{if(*p=='')flag=0; /*遇到空格,flag置0*/elseif(flag==0) /*當(dāng)前字符不是空格,而且flag為0,說明遇到一個(gè)新單詞*/{num++; /*單詞個(gè)數(shù)加1*/flag=1; /*標(biāo)志flag置1,表示新單詞已統(tǒng)計(jì)*/}p++; /*指針p加1,指向下一個(gè)字符*/}return(num); /*返回字符個(gè)數(shù)*/}運(yùn)行程序,從鍵盤輸入字符串“Iwouldliketobeaprogrammer!”輸出結(jié)果是:
Pleaseinputastring: Iwouldliketobeaprogrammer! Thewordsinstrare:7提示:標(biāo)志變量就是編程時(shí)用來對情況的判斷的標(biāo)志,例如本例flag變量就表示值為0表示前一個(gè)字符是空格,如果為1則表示前一個(gè)字符是非空格字符或是還沒開始統(tǒng)計(jì)。這樣通過對標(biāo)志變量的值的判斷,就可以很好的區(qū)分是否遇到了一個(gè)新的單詞,從而進(jìn)行正確的統(tǒng)計(jì)。定義兩個(gè)字符數(shù)組,分別存儲兩個(gè)字符串,用指針指向字符串,將其中一個(gè)字符串復(fù)制到另外一個(gè)字符串。隨堂練習(xí)使用字符串指針變量與字符數(shù)組的區(qū)別1、字符串指針變量本身是一個(gè)變量,用于存放字符串的首地址。也就是說字符串指針變量只能指向字符串,而不能存放字符串。字符數(shù)組則不同,它在內(nèi)存中表示一段連續(xù)的存儲空間,可以用來存放整個(gè)字符串。2、對字符串指針變量賦初值有兩種方式:(1)在定義變量的同時(shí)賦初值,例如:
char*p="It’salongroadtogo.“(2)在定義后初始化,例如把上面語句改為:char*p;p="It’salongroadtogo."知識鏈接3、對字符數(shù)組的情況就不同了。對字符數(shù)組也同樣可以在定義的同時(shí)進(jìn)行初始化,例如:charstr[80]="Hardworkcanmakeupforalackofintelligence."但不能寫成:charstr[80];str="Hardworkcanmakeupforalackofintelligence."如果采用先定義后初始化的方式,則只能采用對字符數(shù)組的各元素逐個(gè)賦值的方式。4、字符數(shù)組一經(jīng)定義后,編譯時(shí)就會為它分配一段連續(xù)的內(nèi)存單元,所以它有確定的地址,字符數(shù)組名就代表該段內(nèi)存單元的起始地址。而定義指針變量時(shí),給指針變量分配內(nèi)存單元,在其中存放一個(gè)地址值,但是該地址值是不確定的,也就是指針變量的指向是不確定的,在把字符串的首地址賦值給指針變量后,該指針才確定保存字符串的首地址。知識鏈接5、指針變量的值是可以改變的。例如:char*p="Yesterdayoncemore."p+=10;printf(“%s”,p);指針p開始指向字符‘Y’,然后指針p的值加10,則指針p指向“once”中的字符‘o’,最后輸出結(jié)果應(yīng)該是:oncemore.而數(shù)組名代表數(shù)組的首地址,它本身的值是不可以改變的。例如下面語句是錯誤的。charstr[]="NowandThen."str++;printf(“%s”,str);學(xué)習(xí)目標(biāo)掌握指針型函數(shù)的用法。掌握用函數(shù)指針調(diào)用函數(shù)以及用函數(shù)指針作為函數(shù)參數(shù)。指針函數(shù)就是函數(shù)返回值為指針型的函數(shù),而函數(shù)指針就是指向函數(shù)的指針。8.5指針函數(shù)與函數(shù)指針案例8-17利用函數(shù)返回的指針引用對應(yīng)的數(shù)據(jù):輸入1~5之間的數(shù)字,輸出對應(yīng)的人名。8.5.1指針函數(shù)char*spstars(intn){staticcharstars[5][10]={"Jordan","James","Kobe","O'neil","Wade"};return(stars[n-1]); /*返回二維數(shù)組第n行的首地址*/}案例程序main(){inti;char*p;printf("Inputyourfavoriteplayer'snumber:");scanf("%d",&i); /*輸入對應(yīng)的號碼*/ p=spstars(i); /*函數(shù)返回的地址保存在指針變量p中*/printf("No.%disyourfavoriteplayer:%s\n",i,p); /*輸出序號和對應(yīng)的人名*/}運(yùn)行程序,從鍵盤輸入序號,比如1,則輸出結(jié)果是:
Inputyourfavoriteplayer’snumber:1 No.1isyourfavoriteplayer:Jordan1、本案例定義了一個(gè)指針函數(shù)(指針型函數(shù))spstars,它的返回值是地址。2、語句staticcharstars[5][10]={“Jordan”,“James”,“Kobe”,“O‘neil”,“Wade”};定義了一個(gè)靜態(tài)二維字符數(shù)組stars.3、返回語句return(stars[n-1]);返回二維數(shù)組第n行的首地址,在二維數(shù)組中stars中,stars[行下標(biāo)]表示該行的首地址,也就是一個(gè)名字字符串的首地址。用n-1來表示下標(biāo)的原因是數(shù)組下標(biāo)是從0開始的,比如序號為1的對應(yīng)行下標(biāo)應(yīng)該是0,序號為n的行下標(biāo)應(yīng)該是n-1。案例分析在函數(shù)spstars中,也可以定義一個(gè)局部指針變量,用該指針變量保存對應(yīng)名字字符串的首地址,在返回時(shí),返回該指針變量的值即可,指針型函數(shù)spstars代碼修改如下:char*spstars(intn){char*p;staticcharstars[5][10]={"Jordan","James","Kobe","O'neil","Wade"};p=stars[n-1]; /*指針p保存對應(yīng)行的首地址*/return(p); /*返回指針p的值就是第n行的首地址*/}提示編寫一個(gè)指針型函數(shù),求出一個(gè)整數(shù)數(shù)組中的最大數(shù)的地址并返回該地址,然后在main函數(shù)中輸出數(shù)組中的最大數(shù)的值和對應(yīng)的下標(biāo)號。隨堂練習(xí)1、在C語言中,允許一個(gè)函數(shù)的返回值是一個(gè)指針(即地址)。2、指針函數(shù)的一般形式是: 類型說明符*函數(shù)名(形參表)
{
函數(shù)體
}指針函數(shù)的定義格式和前面介紹的一般函數(shù)定義格式基本相同,唯一的區(qū)別是在函數(shù)名前加一個(gè)“*”用來表示函數(shù)的返回值是指針類型(即地址)。例如:知識鏈接
float*funcp()
{
函數(shù)體
}這里類型說明符“float”和“*”表示函數(shù)返回值是一個(gè)指針,該指針是指向浮點(diǎn)型(float)的指針。在C語言中,和數(shù)組類似,函數(shù)也是占有一段連續(xù)的內(nèi)存空間,同樣函數(shù)名就是該函數(shù)所占內(nèi)存空間的首地址??梢园押瘮?shù)的首地址保存在一個(gè)指針變量中,使該指針變量指向該函數(shù),然后就可以通過該指針找到并調(diào)用這個(gè)函數(shù)。指向函數(shù)的指針就是函數(shù)指針。8.5.2函數(shù)指針案例8-18用函數(shù)指針調(diào)用函數(shù),求兩個(gè)數(shù)中較大的數(shù)。案例8-18#include<stdio.h>intmax(intx,inty){return(x>y?x:y);}voidmain(){int(*p)(); /*定義指向函數(shù)的指針變量*/案例程序inta,b,c;p=max; /*將max函數(shù)的入口地址賦給函數(shù)指針*/scanf("%d,%d",&a,&b); /*輸入兩個(gè)數(shù)*/c=(*p)(a,b); /*通過指針調(diào)用函數(shù)max*/printf("a=%d,b=%d,max=%d\n",a,b,c);}運(yùn)行程序,結(jié)果是: 輸入:5,9↙
輸出:a=5,b=9,max=91、主函數(shù)中int(*p)();定義指向函數(shù)的指針變量p,它所指向的函數(shù)的返回值是int型。2、賦值語句p=max;表示將函數(shù)的入口地址賦給p。3、調(diào)用函數(shù)用語句c=(*p)(a,b);它等價(jià)于c=max(a,b);案例分析案例分析1、主函數(shù)中int(*p)();定義指向函數(shù)的指針變量p,它所指向的函數(shù)的返回值是int型。2、賦值語句p=max;表示將函數(shù)的入口地址賦給p。3、調(diào)用函數(shù)用語句c=(*p)(a,b);它等價(jià)于c=max(a,b);定義一個(gè)一維數(shù)組,通過函數(shù)指針調(diào)用函數(shù),求數(shù)組的最大元素的值。隨堂練習(xí)1、用函數(shù)指針調(diào)用函數(shù)(*指針變量名)(實(shí)參表)
2、函數(shù)指針變量定義的一般形式是:類型說明符(*指針變量名)(參數(shù));int(*p)();3、用函數(shù)指針調(diào)用函數(shù)的步驟如下:知識鏈接①先定義函數(shù)指針變量,如“int(*p)();”,定義p為函數(shù)指針。②給函數(shù)指針變量賦值為被調(diào)用函數(shù)的入口地址,形式為: 指針變量名=函數(shù)名; 如:p=max;③經(jīng)過步驟(1)、(2)后,就可以通過函數(shù)指針調(diào)用函數(shù),如:(*p)(a,b); 提示:1、int*p();表示指針型函數(shù),即p是函數(shù)名,該函數(shù)返回值是指針(地址)。2、int(*p)();表示函數(shù)指針,即p是指向函數(shù)的指針,該函數(shù)返回值是一個(gè)整數(shù)(值)。編寫一個(gè)函數(shù)calculation()做算術(shù)四則運(yùn)算,每次調(diào)用實(shí)現(xiàn)不同的功能,輸入兩個(gè)數(shù),第一次調(diào)用實(shí)現(xiàn)兩個(gè)數(shù)的加法,第二次實(shí)現(xiàn)兩個(gè)數(shù)的減法,第三次實(shí)現(xiàn)兩個(gè)數(shù)的乘法,第四次實(shí)現(xiàn)兩個(gè)數(shù)的除法。用函數(shù)指針作為參數(shù),即調(diào)用函數(shù)calculation()時(shí),用加減乘除四個(gè)函數(shù)的函數(shù)名作為函數(shù)實(shí)參,在函數(shù)calculation()中,定義指向函數(shù)的指針作為形參來接收加減乘除函數(shù)的入口地址,然后在函數(shù)calculation()中用指向函數(shù)的指針調(diào)用對應(yīng)的加減乘除函數(shù)。隨堂練習(xí)選擇題1、已知:int*p,a;則語句“p=&a;”中的運(yùn)算符“&”的含義是()。A)位與運(yùn)算B)邏輯與運(yùn)算C)取指針內(nèi)容D)取變量地址2、已知:doubled;希望指針變量pd指向d,下面對指針變量pd的正確定義是()。A)doublepd;B)double&pdC)double*pdD)double*(pd)3、若x為整型變量,p是指向整型數(shù)據(jù)的指針變量,則正確的賦值表達(dá)式是()。A)p=&xB)p=xC)*p=&xD)*p=*x
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 馬桶維修合同范本
- 吧臺招聘合同范例
- 分支機(jī)構(gòu)經(jīng)營管理合同范本
- 壓力表送檢合同范本
- 廠房解除租賃合同范本
- 參加招標(biāo)合同范本
- 合同范例 銷售合同范例
- 勞務(wù)合同范本簽約
- 吉林省勞動合同范本
- 山東職業(yè)學(xué)院單招《英語》考試復(fù)習(xí)題庫(含答案)
- 興隆街辦拆遷規(guī)劃方案
- 四年級上冊數(shù)學(xué)計(jì)算題練習(xí)300題及答案
- 《開學(xué)第一課:一年級新生入學(xué)班會》課件
- 右側(cè)腹股溝疝教學(xué)查房
- 人工智能與自動駕駛技術(shù)
- 城市排水系統(tǒng)雨污分流改造
- 數(shù)據(jù)安全法 培訓(xùn)課件
- 法學(xué)涉外法治方向課程設(shè)計(jì)
- 家政服務(wù)員培訓(xùn)課件
- 無人駕駛技術(shù)的傳感器技術(shù)應(yīng)用
評論
0/150
提交評論