c語言程序設(shè)計課件 第7章指針_第1頁
c語言程序設(shè)計課件 第7章指針_第2頁
c語言程序設(shè)計課件 第7章指針_第3頁
c語言程序設(shè)計課件 第7章指針_第4頁
c語言程序設(shè)計課件 第7章指針_第5頁
已閱讀5頁,還剩121頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1第7章

指針2知識回顧-計算機的主要工作流程101010110101101111110111…001110111100010110001111CPU(中央處理器)3內(nèi)存的組織結(jié)構(gòu)內(nèi)部存儲器,是由存儲單元組成的。它的特點是存儲單元是線性連續(xù)的。存儲單元的最小單位是字節(jié)。4如何找到要存儲的數(shù)據(jù)?為了訪問內(nèi)存中的某個存儲單元,我們?yōu)槊恳粋€內(nèi)存的基本存儲單元編號,通過這個編號就可以訪問該單元所存放的數(shù)據(jù)內(nèi)容。這種編號稱為內(nèi)存地址。5變量同地址的關(guān)系系統(tǒng)給變量分配內(nèi)存單元,變量在內(nèi)存中可能會占用幾個連續(xù)的字節(jié),起始字節(jié)的內(nèi)存單元的地址,就是變量的地址。20076還有其它的什么樣的操作方式?77.1指針的基本概念指針:一個變量的地址稱為該變量的指針。指針變量:若一個變量專用于存放另一個變量的地址(指針),則該變量稱為指針變量。8幾個概念-指針、指針變量的關(guān)系…...…...2000200420062005整型變量i5變量i_pointer2001200220032000指針指針變量變量的內(nèi)容變量的地址指針變量變量變量地址(指針)變量值指向地址存入指針變量9直接訪問與間接訪問直接訪問:按變量地址存取變量值間接訪問:通過存放變量地址的變量去訪問變量例

i=3;-----直接訪問指針變量…...…...2000200420062005整型變量i10變量i_pointer20012002200320003例*i_pointer=5;-----間接訪問5107.1.2指針變量的定義一般形式:

類型標(biāo)識符*變量名;例如:int*ptr1,*ptr2;指針變量的類型:指明了該指針指向的內(nèi)存空間所存儲的數(shù)據(jù)類型。

11定義指針變量時要注意的問題:定義中的“*”表示所定義的變量是指針變量,但指針變量名是ptr1、ptr2,而非*ptr1、*ptr2。變量名ptr2前面的“*”不能省略,如果寫成:int*ptr1,ptr2;則ptr2被定義為整型變量,而非整型指針變量。12要注意的問題指針變量只能指向定義時所規(guī)定類型的變量。這個規(guī)定的類型稱為該指針變量的“基類型”。例如:int*ptr1定義指針變量后,并未確定該變量指向何處。也就是說該變量的值是不確定的。在引用指針變量前必須首先讓它指向一個變量,這一點非常重要。137.1.3指針變量的引用指針運算符(“&”和“*”

)“&”(地址運算符):取變量的存儲地址?!?”(引用運算符):是取指針?biāo)赶蜃兞康膬?nèi)容。例:例如:&a是求變量a的地址。

14int

main(void){ inta,b; int*pointer_1,*pointer_2; a=100;b=10; pointer_1=&a; pointer_2=&b; printf(“%d,%d\n”,a,b); printf(“%d,%d\n”,*pointer_1,*pointer_2);}通過指針變量訪問整型變量15對“&”和“*”運算符說明:如果已執(zhí)行了語句pointer_1=&a;(1)&*pointer_1的含義是什么?“&”和“*”兩個運算符的優(yōu)先級別相同,但按自右向左方向結(jié)合。因此,&*pointer_1與&a相同,即變量a的地址。如果有pointer_2=&*pointer_1;它的作用是將&a(a的地址)賦給pointer_2,如果pointer_2原來指向b,經(jīng)過重新賦值后它已不再指向b了,而指向了a。1617(2)

*&a的含義是什么?

先進行&a運算,得a的地址,再進行*運算。*&a和*pointer_1的作用是一樣的,它們都等價于變量a。即*&a與a等價。182.指針的初始化和賦值運算指針的賦值運算:就是把地址賦值給指針變量??梢允且韵氯N方式:用取地址運算符,把地址值賦值給指針變量。把指針變量的值賦給另一個指針變量。給指針變量賦值為符號常量NULL。如:inti,*pi;pi=&i;

如:inti,*pa,*pb;pa=&i;pb=pa;如:int*pi;pi=NULL;

19說明:⑴在定義指針變量時,可以立即將一個地址值賦給指針變量,這就是指針變量的初始化。指針變量的初始化也是指針的賦值運算。如:floatflt,*f_ptr=&flt;

注意:這不是給*f_ptr賦值,而是給指針變量f_ptr賦初值⑵指針變量間的賦值和引用應(yīng)保證基類型相同。若有定義:int*p,i;float*q,x;則:q=&i;╳p=&x;╳20例main(){inti=10;

int*p;

*p=i;

printf(“%d”,*p);}危險!例

main(){inti=10,k;

int*p;

p=&k;*p=i;

printf(“%d,%d”,*p,k););}…...…...2000200420062005整型變量i10指針變量p200120022003隨機21例:指針的概念int

main(void){

inta;

int*pa=&a;a=10;printf("a:%d\n",a);printf("*pa:%d\n",*pa);printf("&a:%x(hex)\n",&a);printf("pa:%x(hex)\n",pa);printf("&pa:%x(hex)\n",&pa);}運行結(jié)果:a:10*pa:10&a:f86(hex)pa:f86(hex)&pa:f88(hex)…...…...f86f8af8cf8b整型變量a10指針變量paf87f88f89f8622例輸入a和b兩個整數(shù),按先大后小的順序輸出a和b。#include<stdio.h>int

main(){int*p1,*p2,*p,a,b;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;

if(a<b)

{p=p1;p1=p2;p2=p;}

printf(“a=%d,b=%d\n\n”,a,b);

printf(“max=%d,min=%d\n”,*p1,*p2);return0;}23運行情況如下:5,9↙a=5,b=9max=9,min=5當(dāng)輸入a=5,b=9時,由于a<b,將p1和p2交換。交換前的情況見圖(a),交換后見圖(b)。24257.1.4指針變量作為函數(shù)參數(shù)同整數(shù)、浮點數(shù)等其它類型的數(shù)據(jù)一樣,指針也可以用作函數(shù)參數(shù)。格式:函數(shù)的返回數(shù)據(jù)類型

函數(shù)名(指針?biāo)赶虻臄?shù)據(jù)類型*指針的名字)例如:int

swap(int*pfirst,int*pSecond)調(diào)用方式:intm=5,n=6;intresult=0;int*pA,*pB;pA=&m;pB=&n;result=swap(pA,pB);26調(diào)用過程的數(shù)據(jù)傳遞:第一步560¥%#mnpApBresult@#4第二步560&mmnpApBresult&n第三步xresultpApB&m&n賦值操作函數(shù)內(nèi)部處理return(x)pFirstpSecond&m&n27另一種說明方式28指針變量作為函數(shù)參數(shù)發(fā)生的效果1、其過程是通過實參給形參賦值2、實際效果是將實參的地址傳遞給了形式

參數(shù)3、因此在函數(shù)內(nèi)部對輸入數(shù)據(jù)的任何操作

都會影響到原始輸入的數(shù)據(jù)。下面看一個例子:注意指針作函數(shù)參數(shù)的寫法注意本例使用的函數(shù)調(diào)用方法29voidswap(int*p1,int*p2);voidmain(){

intx1=100,x2=200;printf("x1=%d,x2=%d\n",x1,x2);swap(&x1,&x2);printf("x1=%d,x2=%d\n",x1,x2);}voidswap(int*p1,int*p2){

inttemp;temp=*p1;*p1=*p2;*p2=temp;}

用指針變量編寫實現(xiàn)兩個數(shù)的交換的函數(shù)1.參數(shù)的傳遞過程2.其它的實現(xiàn)方法(如何正確使用)30swap函數(shù)的錯誤寫法:voidswap(int*p1,int*p2){

int*ptemp;

ptemp=p1;p1=p2;p2=ptemp;}

31例7.3輸入3個整數(shù)a,b,c,按由大到小順

序輸出。使用函數(shù)voidexchange(int*p1,int*p2,int*p3)說明:1.指針做函數(shù)的參數(shù)2.函數(shù)的嵌套調(diào)用327.2指針的運算指針的賦值運算賦值(類型必須匹配)變量地址;數(shù)組名;數(shù)組元素;其它指針;空指針(說明)不能直接給指針變量賦一個整數(shù),如:p=0x1fff;加減運算(+、-)1.指針的±運算2.指針±整數(shù)自加自減運算(++、--、+=、-=)33指針的+、-運算說明:指針與整型值加減的結(jié)果是指針,表示使該指針指向該指針下移或上移存儲單元個數(shù)(整型值)之后的內(nèi)存地址。存儲單元的大小就是該指針?biāo)赶蜃兞康臄?shù)據(jù)類型所需的內(nèi)存大小。例如:ptr+n(指針ptr,n為整數(shù))這個指針值代表的內(nèi)存單元的地址是:ptr+n*d(其中d是指針?biāo)赶蜃兞康臄?shù)據(jù)類型所占內(nèi)存字節(jié)數(shù)),即指針移動了n個元素。34⑵指針與指針的加運算毫無意義,所以指針與指針

沒有加運算。⑶指針與指針的減運算要求相減的兩個指針屬于同一類型,其結(jié)果是整數(shù),表示兩個指針之間的數(shù)據(jù)的個數(shù)。其結(jié)果值的計算公式是:

ptr1-ptr2=(ptr1的值-ptr2的值)/指針的數(shù)據(jù)類型所占的字節(jié)數(shù)例如:

int*ptr1,*ptr2,*ptr3,x;

intary[5]={2,4,8,16,32};ptr1=&ary[0];ptr2=&ary[3];

ptr3=ary;x=ptr2-ptr1;

x的值是3352.指針的++、--、+=、-=運算++、+=:是移動指針到下一個或下幾個存儲單元。

--、-=:是移動指針到上一個或上幾個存儲單元。

例如:int*ptr,ary[5]={2,4,6,8,10};

ptr=ary;ptr+=3;ptr--;想一想:*ptr++和(*ptr)++有什么區(qū)別?36指針的關(guān)系運算 只有在兩個指針變量指向同一數(shù)組中元素的情況下才能用關(guān)系運算符進行比較。P144-例7.4377.3指針與數(shù)組數(shù)組中每一個元素都有對應(yīng)的地址,因此可以通過指針訪問數(shù)組:第一種:直接訪問數(shù)組元素第二種:通過指針引用數(shù)組元素inta[10]={0};int*pA,*pB;pA=&a[3];pB=&a[0];inta[10]={0};

int*pA,nTemp;

pA=&a[3];

nTemp=*(pA+1);38說明1:對于數(shù)組名,在C語言中規(guī)定數(shù)組名代表數(shù)組的首元素的地址。也就是說可以把數(shù)組名當(dāng)作一個地址來看待。因此可將數(shù)組名賦值給一個指針,并通過指針的移動來訪問數(shù)組中的每個元素。inta[10]={0};int*pA,nTemp;pA=a;nTemp=*(pA+1);inta[10]={0};int*pA,nTemp;pA=&a[0];nTemp=*(pA+1);39說明2:由于數(shù)組名是地址,因此也可以使用引用(取內(nèi)容)操作符“*”來進行數(shù)組元素的訪問。如:inta[10]={0};int*pA,nTemp;pA=a;nTemp=*(pA+1);inta[10]={0};int*pA,nTemp;nTemp=*(a+1);401.用下標(biāo)法引用數(shù)組元素如:a[3]=45;b[2][5]=200;p[1]=1002.用指針法引用數(shù)組元素(兩種)假如:inta[10],*p,i;p=a;則:⑴*(p+i)、*(a+i)都可以訪問元素a[i]

*(p+i)、*(a+i)、a[i]、p[i]對數(shù)組變量的引用方法等價,都代表數(shù)組a的第i+1個元素(1)對數(shù)組元素的引用方法41例7.5:輸出10個元素數(shù)組中的全部元素。方法二:通過數(shù)組名計算數(shù)組元素地址,找出元素的值。

int

main(){

inta[10]={54,65,8,2,3,56,8,21,57,98},i;

for(i=0;i<10;i++)printf("%4d",*(a+i));}方法一:下標(biāo)法。

int

main(){

inta[10]={54,65,8,2,3,56,8,21,57,98},i;

for(i=0;i<10;i++)printf("%4d",a[i]);}42方法三:用指針變量指向數(shù)組元素

int

main(){

inta[10]={54,65,8,2,3,56,8,21,57,98},*p,i;p=a;

for(i=0;i<10;i++)printf("%4d",*p++);}以上三種方法,利用指針變量效率最高。

說明:⑴指針變量與數(shù)組名的區(qū)別:

指針變量是地址變量,數(shù)組名是地址常量。即指針變量的內(nèi)容可以在程序運行過程中被改變;而數(shù)組名一旦被定義,它的值就不能被改變了。

例如:inti,*p,a[6];則:p=&i;√a=&i;a++;a+=i;不能給常量賦值43⑵利用指針變量編程時特別要注意指針變量的當(dāng)前值。例7.6:通過指針變量輸入輸出a數(shù)組元素。main(){int*p,i,a[5];p=a;

for(i=0;i<5;i++)scanf("%d",p++);

for(i=0;i<5;i++)printf(“%6d”,*p++);}應(yīng)插入語句p=a;44在使用指針變量指向數(shù)組元素時,應(yīng)切實保證指向數(shù)組中有效的元素,如a[10]在編譯時并不出錯,而按*(a+10)處理,但得不到預(yù)期的結(jié)果*p++和*++p的不同*p++和(*p)++的不同45數(shù)組名作函數(shù)的參數(shù)例如:

f(int

arr[],intn){……}main(){intarray[10];……f(array,10);……}解釋:實際上,C編譯系統(tǒng)都是將形參數(shù)組名作為指針變量來處理的。上例中f(int

arr[],intn)等價于f(int*arr,intn)

。使用形參數(shù)組的概念只是為了與實參數(shù)組對應(yīng)、直觀、便于理解而已。46例:從10個數(shù)中找出其中最大值和最小值。voidmax_min(int

a[],int

n,int*max,int*min);intmain(){

int

i,a[]={2,4,1,6,7,32,45,75,45,90},max,min;

printf("Theoriginalarray=");

for(i=0;i<10;i++)printf("%5d",a[i]);max_min(a,10,&max,&min);

printf("max=%dmin=%d",max,min);}voidmax_min(inta[],intn,int*max,int*min){

inti;*max=*min=a[0];

for(i=0;i<n;i++){if(*max<a[i])*max=a[i];if(*min>a[i])*min=a[i];}}47上例中如果形參數(shù)組用指針變量,則程序如下:voidmax_min(int*x,int

n,int*max,int*min);main(){

inti,a[10]={2,4,1,6,7,32,45,75,45,90},max,min;

printf("Theoriginalarray=");

for(i=0;i<10;i++)printf("%5d",a[i]);max_min(a,10,&max,&min);

printf(“max=%dmin=%d",max,min);}voidmax_min(int*x,intn,int*max,int*min){

inti;*max=*min=*x;

for(i=1;i<n;i++,x++){if(*max<*x)*max=*x;if(*min>*x)*min=*x;}}48數(shù)組名做函數(shù)參數(shù)小結(jié):如果有一個實參數(shù)組,想在函數(shù)中改變此數(shù)組的元素的值,實參與形參都可用數(shù)組名或指針變量其對應(yīng)關(guān)系有以下4種情況:(P177-178)⑴實參與形參都用數(shù)組名;⑵實參用數(shù)組名、形參用指針變量;⑶實參、形參都用指針變量;⑷實參為指針變量、形參用數(shù)組名。49例:實參、形參都用指針變量的形式main(){inta[10],*p;p=a;……f(p,10);……}f(int*x,intn){……

}例:實參為指針變量,形參用數(shù)組名。main(){inta[10],*p;p=a;……f(p,10);……}f(intx[],intn){……

}50使用指針時候的重要說明注意:用指針變量作實參時一定要有確定的值。f(intx[],intn){……}main(){inta[10],*p;……

f(p,10);}main(){int*p,i;for(i=0;i<10;i++)scanf(“%d”,p++);

}51練習(xí):選擇法從大到小排序/**/main(){

int*p,i,a[10];

p=a;

for(i=0;i<10;i++)scanf(“%d”,p++);

p=a; sort(p,10);

for(p=a,i=0;i<10;i++){printf(“%d

”,*p);p++;}

printf(“\n”);}為什么52兩類寫法sort(intx[],intn){

int

i,j,k,t;

for(i=0;i<n-1;i++){ k=i;

for(j=i+1;j<n;j++) {

if(x[j]>x[k])k=j; }

if(k!=i) {t=x[i];

x[i]=x[k];

x[k]=t; }}}sort(int*x,intn){

int

i,j,k,t;

for(i=0;i<n-1;i++){ k=i;

for(j=i+1;j<n;j++) { if(*(x+j)>*(x+k))k=j; }

if(k!=i) {t=*(x+i); *(x+i)=*(x+k); *(x+k)=t; }}}537.3.2指針與字符串字符串/字符數(shù)組回顧:定義:charstr[10];初始化:charstr[]=“helloworld”charstr[]={‘h’,’e’,’l’,’l’,’o’}輸出:printf(“%s”,str);printf(“%c”,str[1]);

puts(str);輸入:gets(str);scanf(“%s”,str)scanf(“%s%s%s”,str1,str2,str3)54用指針處理字符串定義:char*pstr;初始化:char*pStr=“helloworld”;char*pStr;pStr=“helloworld”;輸出:printf(“%s”,pStr);printf(“%c”,*(pStr+i));輸入:一般需要借助數(shù)組來完成55字符指針變量和字符數(shù)組的異同概念字符數(shù)組由若干個元素組成,每個元素中放一個字符。而字符指針變量中存放的是地址(字符串的首地址)(僅僅占一個指針變量所占用的空間大?。?,而不是將整個字符串都放到字符指針變量中。56字符指針變量和字符數(shù)組的異同初始化:字符數(shù)組和字符指針變量都可以在定義時賦初值但以下方法對字符數(shù)組非法,對字符指針變量合法

chars[10];s=“hello!”;╳

char*ps;ps=“hello!”;√57字符指針變量和字符數(shù)組的異同字符數(shù)組名是指針常量,只能表示一個確定的字符串,不能改變。不能進行++,--等運算來改變其位置,而字符指針變量的值是可以改變的,它可以代表不同的字符串。若定義了一個指針變量,并使它指向一個字符串,就可以用下標(biāo)形式引用指針變量所指向字符串中的字符。如:char*a=“IloveChina!”;printf(“%c”,a[5]);

58字符指針變量和字符數(shù)組的異同字符指針變量定義后,必須先被賦值后使用,而定義一個字符數(shù)組后即可馬上使用例:charst[10];scanf(“%s”,st);char*s;scanf(“%s”,s);(錯)應(yīng)改為:

chara[20],*s;

s=a;(注意:這步必不可少)

scanf(“%s”,s);59例:將字符串a(chǎn)復(fù)制給字符串b。intmain(){chara[]=“Iamaboy",b[20];

inti=0;do{*(b+i)=*(a+i);i++;}while(*(a+i)!=‘\0’);/*也可寫成while(*(a+i));*/

*(b+i)=‘\0’;

puts(b);}60上例程序還可寫成:intmain(){

chara[]=“Iamaboy",b[20],*p1=a,*p2=b;

inti=0;do{

*p2=*p1;p2++;p1++;}while(*p1!='\0');/*也可寫成while(*p1);*/

*p2=‘\0’;

puts(b);}61字符串指針作函數(shù)的參數(shù)同指針作函數(shù)參數(shù)一樣,可以在子函數(shù)中改變字符數(shù)值,并在主函數(shù)中得到相應(yīng)的變化內(nèi)容。例:用函數(shù)調(diào)用實現(xiàn)字符串的復(fù)制62main(){ chara[]=“Iamateacher.”; charb[]=“Youareastudent.”;

printf(“stringa=%s\nstringb=%s\n”,a,b);

copy_string(a,b);

printf(“stringa=%s\nstringb=%s\n”,a,b);}用字符數(shù)組作參數(shù)voidcopy_string(char

from[],charto[]){

inti=0;

while(from[i]!=‘\0’){to[i]=from[i];i++;}

to[i]=‘\0’;}使用指針的方式voidcopy_string(char*from,char*to){ for(;*from!=‘\0’;from++,to++)*to=*from; *to=‘\0’;}使用指針的方式voidcopy_string(char*from,char*to){ while(*to++=*from++);}637.3.3指針和二維數(shù)組多維數(shù)組的回顧:定義:inta[3][4];訪問其中的一個元素:a[2][1];如何訪問第二行元素:a[1]存儲方式:圖為什么可以使用a[1]來訪問第二行元素?C語言中多維數(shù)組的概念模型64多維數(shù)組概念模型以二維數(shù)組為例:在C語言中,一個二維數(shù)組可以看成是一個一維數(shù)組,其中每個元素又是一個包含若干元素的一維數(shù)組。(圖)

假如有定義:inta[2][3];則C語言編譯程序認(rèn)為a數(shù)組是由a[0],a[1]兩個元素組成的一維數(shù)組,a[0]和a[1]分別是包含三個元素的一維數(shù)組名,分別代表a數(shù)組元素的起始地址(即a[0]是第0行元素的首地址,a[1]是第1行元素的首地址)。a和a[0]是兩個基類型不同的指針常量(再次說明)。65指針操作多維數(shù)組的基本知識數(shù)組名字的含義和操作設(shè)有一個二維數(shù)組;假設(shè)數(shù)組地址從2000開始inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}}考慮a,a[0],a[1][2]的意義考慮a+1,a[0]+1,a[1][2]+1的含義考慮*(a+1),*(a[0]+1),*(a[1][2]+1)考慮&(a+1),&(a[0]+1),&(a[1][2]+1)…66a[1][2]和a的意義a[1][2]是元素的地址a代表二維數(shù)組首元素的地址,首元素不是一個整型變量,而是由4個整型元素所組成的一維數(shù)組,因此a代表的是首行的首地址*a代表0行0列的地址即&a[0][0]如果首行首地址是2000,則a+1是多少?a+2是多少?

a+1的地址:2008;a+2的地址:2016a[1][2]是元素的內(nèi)容67a[i]是一維數(shù)組名,是一個地址,它以數(shù)組的第一個元素的地址,作為地址。a[0]代表一維數(shù)組a[0]中第0列元素的地址,即&a[0][0],值為2000a[1]代表&a[1][0],值為2008a[i]的意義68a+i是指向行的指針,a[i]+j是指向列的指針a[1]和*(a+1)等價&a[0]與a等價*和&操作符69數(shù)組a的性質(zhì)表示形式含義值a二維數(shù)組名,指向一維數(shù)組a[0],即第0行首地址2000a[0],*(a+0),*a第0行第0列元素的地址2000a+1,&a[1]第1行首地址2008a[1],*(a+1)第1行第0列元素a[1][0]的地址2008a[1]+2,*(a+1)+2,&a[1][2]第1行第2列元素a[1][2]的地址2012*(a[1]+2),*(*(a+1)+2),a[1][2]第1行第2列元素a[1][2]的值1370為什么a+1和*(a+1)都是2008呢?

a+1是a中第1行的首地址,而*(a+1)就是a[1],是指向a[1][0]的地址,二者值相同,但含義不同71&a[i]和a[i](元素地址)的值相同,但含義不同&a[i]或a+i指向行,即第i行a[i]或*(a+i)指向列,即第i行第0個元素72/*例*/#defineFORMAT“%d,%d\n”intmain(){

inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

printf(FORMAT,a,*a); printf(FORMAT,a[0],*(a+0)); printf(FORMAT,&a[0],&a[0][0]); printf(FORMAT,a[1],a+1); printf(FORMAT,&a[1][0],*(a+1)+0); printf(FORMAT,a[2],*(a+2)); printf(FORMAT,&a[2],a+2); printf(FORMAT,a[1][0],*(*(a+1)+0));}73指向多維數(shù)組元素的指針變量指針可以用來指向二維甚至更高維的數(shù)組元素,但是需要注意高維數(shù)組的行、列定義。例如:

inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

int*p;

是否可以寫p=a;???分析:如果正確賦值必須左右兩端的數(shù)據(jù)類型需要一致,a指向的元素是一維數(shù)組,而p指向的元素是int,因此這里不匹配可以使用的賦值方式:P=a[0]P=*(a+0)P=*aP=&a[0][0]74用指針變量輸出二維數(shù)組元素的值main(){

inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

int*p;

for(p=a[0];p<a[0]+12;p++) { if((p-a[0])%4==0)printf(“\n”); printf(“%4d”,*p); }}75指向數(shù)組的指針(二)特點:其指向的數(shù)據(jù)類型是數(shù)組,而不是簡單的數(shù)據(jù)類型定義:數(shù)據(jù)類型(*指針名稱)[數(shù)組尺寸]例如:int(*p)[4]含義:本身是一個指針變量,其指向的數(shù)據(jù)類型是包含4個元素的數(shù)組,這個數(shù)組中的元素是int型的。是否可以進行p=a;…其它方式76繼續(xù)上一題main(){

inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

int

(*p)[4]=a; for(…?) { printf(“%4d”,???); }}77用指向數(shù)組的指針作函數(shù)參數(shù)將多維數(shù)組向一個函數(shù)中進行傳遞的時候,可以采用的方法有多維數(shù)組名作參數(shù)使用指向元素的指針進行數(shù)據(jù)傳遞funName(int*p,int

col,introw)使用指向數(shù)組的指針進行數(shù)據(jù)傳遞funName(int(*p)[4],introw)例子:7.12有一個班,3個學(xué)生,各學(xué)4門課,計算總平均分?jǐn)?shù),以及第n個學(xué)生的成績78main(){ voidaverage(float*p,intn); voidsearch(float(*p)[4],intn); floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}}; average(*score,12); search(score,2);}voidaverage(float*p,intn){ float*p_end; floatsum=0,aver;

p_end=p+n-1;

for(;p<=p_end;p++) sum=sum+(*p); aver=sum/n;

printf(“average=%5.2f\n”,aver);}voidsearch(float(*p)[4],intn){

inti;

printf(“thescoreofNo.%dare:\n”,n);

for(i=0;i<4;i++) printf(“%5.2f”,*(*(p+n)+i));}79例:在上例的基礎(chǔ)上,查找一門以上課程不及格的學(xué)生,打印出他們的全部課程的成績voidsearch(float(*p)[4],intn){

int

i,j,flag;

for(j=0;j<n;j++){ flag=0;

for(i=0;i<4;i++) if(*(*(p+j)+i)<60)flag=1;

if(flag==1){

printf(“No.%dfails,hisscoresare:\n”,j);

for(i=0;i<4;i++)printf(“%5.2f”,*(*(p+j)+i));

printf(“\n”);}}}80小結(jié):指針存取數(shù)組元素的優(yōu)點通過指針變量存取數(shù)組元素速度快。用指針變量作函數(shù)的形式參數(shù),所處理的數(shù)組大小可以變化(特別是在處理多維數(shù)組的情況下),因此書寫的程序很靈活。817.4函數(shù)的指針和指向函數(shù)的指針變量函數(shù)在運行的時候被分配給一個地址。程序在運行的時候,所有的調(diào)用函數(shù)過程都是從這個地址開始運行的。這個地址被就稱為函數(shù)的入口地址(指針)。因此可以使用指針變量指向這個函數(shù)的入口地址。并通過這個指針變量來調(diào)用此函數(shù)。82指向函數(shù)的指針變量定義指向函數(shù)的指針的一般形式:類型標(biāo)識符(*指針變量名)(形式參數(shù)類型列表)例如:int

(*p)(int,int);含意:p是一個指向函數(shù)的指針,這個函數(shù)中有兩個參數(shù)其類型都是int型的,同時這個函數(shù)的返回值是一個int型的如何使用83#include<stdio.h>void

main(){intmax(int,int);

int

a,b,c;

scanf(″%d,%d″,&a,&b);c=max(a,b);

printf(″a=%d,b=%d,max=%d

″,a,b,c);}

intmax(int

x,int

y){int

z;

if(x>y)z=x;

elsez=y;

return(z);}求a、b的較大值84#include<stdio.h>void

main(){int

max(inta,intb);

int(*p)(int,int);/*定義*/

int

a,b,c;

p=max;/*賦值只給函數(shù)名不給參數(shù)*/

scanf(″%d,%d″,&a,&b);

c=(*p)(a,b);/*使用*/

printf(″a=%d,b=%d,max=%d″,a,b,c);}使用函數(shù)指針85說明:注意:不能寫成p=max(a,b);pmaxp=max;/*賦值*/使用方式:c=(*p)(a,b)86用指向函數(shù)的指針作函數(shù)參數(shù)函數(shù)指針變量常用的用途之一是把指針作為參數(shù)傳遞到其他函數(shù)。指向函數(shù)的指針也可以作為參數(shù),以實現(xiàn)函數(shù)地址的傳遞,這樣就能夠在被調(diào)用的函數(shù)中使用實參函數(shù)。使用函數(shù)做參數(shù)增加了函數(shù)的靈活性。這一種使用方法在現(xiàn)代程序設(shè)計中得到了非常廣泛的應(yīng)用,c++語言的多種概念的實現(xiàn)就是以這種方式來完成的(例如:多態(tài))87實參函數(shù)名f1

f2↓↓voidsub(int(*x1)(int),int(*x2)(int,int))/*定義頭*/{int

a,b,i,j;a=(*x1)(i);/*調(diào)用f1函數(shù)*/b=(*x2)(i,j);/*調(diào)用f2函數(shù)*/

}原理簡述:88設(shè)一個函數(shù)process,在調(diào)用它的時候,每次實現(xiàn)不同的功能。輸入a和b兩個數(shù),第一次調(diào)用process時找出a和b中大者,第二次找出其中小者,第三次求a與b之和。#include<stdio.h>voidmain(){intmax(int,int);/*函數(shù)聲明*/

intmin(int,int);/*函數(shù)聲明*/

intadd(int,int);/*函數(shù)聲明*/voidprocess(int,int,int(*fun)(int,int));/*函數(shù)聲明*/

int

a,b;

printf(″enteraandb:″);

scanf(″%d,%d″,&a,&b);89intmax(int

x,int

y)/*函數(shù)定義*/{int

z;

if(x>y)z=x;

elsez=y;

return(z);}intmin(int

x,int

y)/*函數(shù)定義*/

{int

z;

if(x<y)z=x;

elsez=y;

return(z);}

函數(shù)90

printf(″max=″);

process(a,b,max);

printf(″min=″);

process(a,b,min);

printf(″sum=″);

process(a,b,add);}使用方法91intadd(int

x,int

y)/*函數(shù)定義*/{intz;z=x+y;

return(z);}voidprocess(int

x,int

y,int(*fun)(int,int)){intresult;

result=(*fun)(x,y);

printf(″%d\n″,result);}函數(shù)的指針做參數(shù)的實現(xiàn)方式927.5指針型函數(shù)一個函數(shù)可以帶回一個整型值、字符值、實型值等,也可以帶回指針型的數(shù)據(jù),即地址。其概念與以前類似,只是帶回的值的類型是指針類型而已。這種帶回指針值的函數(shù),一般定義形式為類型名*函數(shù)名(參數(shù)表列);例如:int*a(int

x,int

y);含義:名稱為a的函數(shù)中有兩個參數(shù)x,y返回一個指向int類型的指針。93例有若干個學(xué)生的成績(每個學(xué)生有4門課程),要求在用戶輸入學(xué)生序號以后,能輸出該學(xué)生的全部成績。用返回指針的函數(shù)來實現(xiàn)。

#include<stdio.h>voidmain(){floatscore[][4]={{60,70,80,90},

{56,89,67,88},{34,78,90,66}};float*search(float(*pointer)[4],intn);

float*p;

int

i,m;

printf(″enterthenumberofstudent:″);

scanf(″%d″,&m);

printf(″ThescoresofNo.%dare:\n″,m);

94

p=search(score,m);

for(i=0;i<4;i++)

printf(″%5.2f\t″,*(p+i));}float*search(float(*point)[4],int

n){float*pt;

pt=*(point+n);/*pt=point?*/return(pt);}

運行情況如下:enterthenumberofstudent:1↙ThescoresofNo.1are:56.0089.0067.0088.00957.6指針數(shù)組和指向指針的指針7.6.1指針數(shù)組的概念一個數(shù)組,若其元素均為指針類型數(shù)據(jù),稱為指針數(shù)組,也就是說,指針數(shù)組中的每一個元素都相當(dāng)于一個指針變量。一維指針數(shù)組的定義為:類型名*數(shù)組名[數(shù)組長度];例如:int*p[4];應(yīng)用:指針數(shù)組通常用來處理字符串問題96指針數(shù)組在處理字符串方面的一些特點1、精簡的內(nèi)存分配空間圖示2、快速的數(shù)據(jù)操作能力不必對數(shù)組中的每一個元素進行操作例題:

將若干字符串按字母順序(由小到大)輸出。9798#include<stdio.h>#include<string.h>voidmain(){

char*name[]={“Followme”,“BASIC”,“GreatWall″,”FORTRAN“,”Computerdesign“};/*初始化方式*/

int

n=5;

sort(name,n);

print(name,n);}99voidsort(char*name[],int

n){char*temp;

int

i,j,k;

for(i=0;i<n-1;i++){k=i;

for(j=i+1;j<n;j++)

if(strcmp(name[k],name[j])>0)k=j;

if(k!=i) {

temp=name[i];name[i]=name[k];name[k]=temp;}}}

選擇排序(指針數(shù)組做函數(shù)參數(shù))如何使用100voidprint(char*name[],int

n){int

i;

for(i=0;i<n;i++)

printf(″%s\n″,name[i]);

}還可以如何寫*(name++)Name[0]Name[1]Name[2]Name[3]Name[4]FollowmeBASICGreatWallFORTRANComputerdesign101指向指針的指針定義:指向指針數(shù)據(jù)的指針變量格式數(shù)據(jù)類型**指針名稱;例如:char**pCh;說明:本身仍然是一個指針,特點在于指向的數(shù)據(jù)類型用來靈活操作指針數(shù)組102例:使用指向指針的指針。

#include<stdio.h>voidmain(){char*name[]={"Followme","BASIC","GreatWall″,"FORTRAN","Computerdesign"};char**p;/*通常不用其進行初始化*/

int

i;

for(i=0;i<5;i++){p=name+i;/*賦值方式*/

printf(″%s\n″,*p);/*使用方式*/

}}103#include<stdio.h>voidmain(){int

a[5]={1,3,5,7,9};

int*num[5]={&a[0],&a[1],/*為什么這么寫*/&a[2],&a[3],&a[4]};

int**p,i;p=num;

for(i=0;i<5;i++){printf(″%d″,**p);/*寫成*p會如何?*/

p++;}}例

一個指針數(shù)組的元素指向整型數(shù)據(jù)的簡單例子104指針數(shù)組可以作main函數(shù)的形參指針數(shù)組也可以作函數(shù)的參數(shù)在做main函數(shù)的參數(shù)的時候,通過命令行參數(shù)來進行函數(shù)的調(diào)用。例如:voidmain(int

argc,charargv[])命令行的一般形式為命令名參數(shù)1參數(shù)2……參數(shù)n105例如一個名為file1的文件,它包含以下的main函數(shù):voidmain(int

argc,char*argv[]){while(argc>1){++argv;

printf(″%s\n″,*argv);--argc;}}在DOS命令狀態(tài)下輸入的命令行為file1ChinaBeijing則執(zhí)行以上命令行將會輸出以下信息:ChinaBeijing106有關(guān)指針的數(shù)據(jù)類型和指針運算的小結(jié)指針指向的各種數(shù)據(jù)類型指針同數(shù)組的聯(lián)系與區(qū)別指針可以進行的運算回顧使用指針的注意事項107定義含義inti;定義整型變量iint*p;p為指向整型數(shù)據(jù)的指針變量inta[n];定義整型數(shù)組a,它有n個元素int*p[n];定義指針數(shù)組p,它由n個指向整型數(shù)據(jù)的指針元素組成int(*p)[n];p為指向含n個元素的一維數(shù)組的指針變量intf();f為帶回整型函數(shù)值的函數(shù)int*p();p為帶回一個指針的函數(shù),該指針指向整型數(shù)據(jù)int(*p)();p為指向函數(shù)的指針,該函數(shù)返回一個整型值int**p;p是一個指針變量,它指向一個指向整型數(shù)據(jù)的指針變量指針指向的各種數(shù)據(jù)類型108int**(*p)(int(*p1)[4],int*p1[4])109指針和數(shù)組的聯(lián)系與區(qū)別指針在操作上完全可以同數(shù)組的操作等價,但是數(shù)組的操作不能同指針等價。例如:char*p的初始化關(guān)鍵的原因在于數(shù)組分配數(shù)據(jù)的內(nèi)存,而指針不進行分配。110指針可以進行的運算回顧(1)指針變量加(減)一個整數(shù)例如:p++、p--、p+i、p-i、p+=i、p-=i等。(2)賦值(將一個變量地址賦給一個指針變量)p=&a;(將變量a的地址賦給p)p=array;(將數(shù)組array首元素地址賦給p)p=&array[i];(將數(shù)組array第i個元素的地址賦給p)p=max;(max為已定義的函數(shù),將max的入口地址賦給p)p1=p2;(p1和p2都是指針變量,將p2的值賦給p1)111賦值NULL(3)指針進行減法運算前提是指針指向的內(nèi)容一致(數(shù)組中的元素)(4)指針進行比較前提是指針指向同一數(shù)組中的元素(5)指針的轉(zhuǎn)換void類型,強制轉(zhuǎn)換的方法112使用指針的注意指針很靈活,因此使用的時候要注意:指針要進行初始化,不能讓其懸空。指針是地址的代名詞,因此其中只能裝入地址即使是地址,也要注意指針指向的數(shù)據(jù)類型是否一致。注意*和&兩個特殊的運算符注意*在多維數(shù)組中的用途A[i]同*(a+i)的關(guān)系要牢記113習(xí)題輸入3個數(shù),按從小到大順序輸出swap(int

x,inty){inttemp;temp=x;x=y;y=te

溫馨提示

  • 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

提交評論