




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第6章指針6.1指針定義與使用6.2指針與函數(shù)6.3指針與數(shù)組6.4指針與字符串6.5指針數(shù)組與多級(jí)指針6.6指針與動(dòng)態(tài)內(nèi)存分配6.7指針的深層應(yīng)用第6章指針6.1指針定義與使用16.1指針的引出一.地址與指針
1.地址與取地址運(yùn)算
C程序中的變量在內(nèi)存中占有一個(gè)可標(biāo)識(shí)的存儲(chǔ)區(qū),
每一個(gè)存儲(chǔ)區(qū)是由若干個(gè)字節(jié)組成,每一個(gè)字節(jié)都有自己的地址,而一個(gè)存儲(chǔ)區(qū)的地址是指該存儲(chǔ)區(qū)中第一個(gè)字節(jié)的地址C語(yǔ)言允許在程序中使用變量的地址(通過(guò)地址運(yùn)算符&可得到)
如:floatx;
變量x的地址----&x
inta[10];
數(shù)組變量a的地址----數(shù)組名a
6.1指針的引出一.地址與指針C語(yǔ)言允許在程序中使用變22.指針與指針變量(1)變量的訪問(wèn)方式①直接訪問(wèn):通過(guò)變量名或地址訪問(wèn)變量的存儲(chǔ)區(qū)
例:scanf(“%d”,&x);
x=sqrt(x);printf(“%d”,x);②間接訪問(wèn):將一個(gè)變量的地址存放在另一個(gè)變量中.
如將變量x的地址存放在變量p中,訪問(wèn)x時(shí)先找到p,
再由p中存放的地址找到xpx201210101010(2)指針:一個(gè)變量的指針就是該變量的地址(指針就是地址)(3)指針變量:存放變量地址的變量,它用來(lái)指向另一個(gè)變量2.指針與指針變量②間接訪問(wèn):將一個(gè)變量的地址存放在3
二、指針變量的定義1.格式:數(shù)據(jù)類型
*指針變量名;
例int*p1;char*p2;2.說(shuō)明:(1)在變量定義時(shí),*號(hào)表示該變量是指針變量
(注意:指針變量是p1,p2,不是*p1,*p2)(2)定義指針變量后,系統(tǒng)為其分配存儲(chǔ)空間,用以存放其他變量的地址,但在對(duì)指針變量賦值前,它并沒(méi)有確定的值,也不指向一個(gè)確定的變量例:intx,*p;x=5;px2012101051234注:指針變量p的值是隨機(jī)值,
此時(shí)p和x并無(wú)關(guān)聯(lián)二、指針變量的定義2.說(shuō)明:例:intx4(3)使指針變量指向一個(gè)確定的變量必須進(jìn)行賦值intx,*p;x=5;p=&x;px2012101051010三、指針變量的引用1.指針運(yùn)算符*(1)p與*p不同,p是指針變量,p的值是p所指向的變量的地址*p是p所指向的變量,*p的值是p所指向的變量的值*p的值為5(*p表示x),而p的值為1010(2)引用指針變量時(shí)的*與定義指針變量時(shí)的*不同定義變量時(shí)的*只是表示其后的變量是指針變量
(3)使指針變量指向一個(gè)確定的變量必須進(jìn)行賦值5inta,*p;p=&a;
scanf(“%d”,p);printf(“%d\n”,*p);*p=12;
printf(“%d\n”,*p);pa201210105101012讓p指向a
對(duì)a重新賦值等價(jià)于a=12
即&a2.&與*
p=&a;
*&a*(&a)*pa&*p&(*p)&ainta,*p;pa201210105162abcd53.*與++,--inta=2,b=5,c,d,*p;p的值為a的地址,*p的值為2p的值不變,*p的值為3(2)c=*p++;
c=*(p++);{c=*p;p++;}
執(zhí)行后c的值為3,*p的值為5(3)d=*++p;
d=*(++p);{++p;d=*p;}
執(zhí)行后d的值為3,*p的值為3p201210101010(1)p=&a;(*p)++;(等價(jià)于
a++;)101233101432a53.*與++,--p的值7例6.2#include<stdio.h>voidmain(){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”,a,b);printf(“max=%d,min=%d\n”,*p1,*p2);}abp1p2p&a&b&a&b&a59輸出結(jié)果:a=5,b=9max=9,min=5例6.2abp1p2p&a&b&a&b&a59輸出結(jié)果:8一、指針變量作函數(shù)參數(shù)例:2個(gè)數(shù)按大小順序輸出#include<stdio.h>voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}voidmain(){inta,b;scanf(“%d%d”,&a,&b);if(a<b)swap(a,b);printf(“a=%d,b=%d\n”,a,b);}abxytemp5說(shuō)明:該程序不能實(shí)現(xiàn)a和b的交換因?yàn)閷?shí)參a,b
對(duì)形參x,y
是“值傳遞”,x和y
的變化不影響a和b
所以輸出為:a=5,b=99mainswap559956.2指針與函數(shù)一、指針變量作函數(shù)參數(shù)例:2個(gè)數(shù)按大小順序輸出abxyt9例6.3①#include<stdio.h>voidswap1(int*p1,int*p2){inttemp;
temp=*p1;*p1=*p2;*p2=temp;}voidmain(){inta,b,*pt1,*pt2;scanf(“%d%d”,&a,&b);pt1=&a;pt2=&b;if(a<b)swap1(pt1,pt2);printf(“a=%d,b=%d\n”,a,b);}abp1p2temp&b&apt1pt25說(shuō)明:這種方法是交換p1和p2所指向的變量的值,即交換main函數(shù)中a和b的值所以輸出為:a=9,b=5mainswap159&a&b95例6.3①abp1p2temp&b&apt1pt25說(shuō)10例6.3②#include<stdio.h>voidswap2(int*p1,int*p2){int*temp;
*temp=*p1;*p1=*p2;*p2=*temp;}說(shuō)明:這種方法可能會(huì)破壞系統(tǒng)的正常工作狀態(tài),因?yàn)閠emp是一個(gè)指針變量但是在函數(shù)中并沒(méi)有給temp一個(gè)確定的地址,這樣它所指向的內(nèi)存單元是不可預(yù)見(jiàn)的,而對(duì)*temp的賦值可能帶來(lái)危害abpt1pt2main&a&bp1p2temp&b&aswap2?隨機(jī)值55959例6.3②說(shuō)明:這種方法可能會(huì)破壞系統(tǒng)的正常abpt11例6.3③#include<stdio.h>voidswap3(int*p1,int*p2){int*p;
p=p1;p1=p2;p2=p;}p1p2p&a&a&b這種方法是交換形參p1和p2的值,使它們的指向發(fā)生改變,但是main函數(shù)中的a和b的值并沒(méi)有進(jìn)行交換所以輸出為:a=5,b=95a9b&apt1&bpt2main&b&aswap3例6.3③p1p2p&a&a&b這種方法是交換形參p112
前面我們用到的函數(shù),有些無(wú)返回值,有些有返回值,返回值類型多為int,float,char.一個(gè)函數(shù)的返回值也可以是一個(gè)指針類型的數(shù)據(jù)(即地址)定義函數(shù):數(shù)據(jù)類型
*函數(shù)名(形參表列)
{函數(shù)體;}
例:int*fun(inta,intb){函數(shù)體;}
說(shuō)明:定義一個(gè)返回指針值的函數(shù)與以前定義函數(shù)格式基本類似,只是在函數(shù)名前加*
,它表明該函數(shù)返回一個(gè)指針值,而這個(gè)指針值是指向一個(gè)int型數(shù)據(jù)二、函數(shù)返回指針前面我們用到的函數(shù),有些無(wú)返回值,有些有13例:#include<stdio.h>#include<string.h>#defineSIZE100charbuf[SIZE];char*p=buf;char*alloc(intn){char*begin;if(p+n<=buf+SIZE){begin=p;
p=p+n;
return(begin);}elsereturn(NULL);}voidmain(){char*p1,*p2;inti;
p1=alloc(10);
strcpy(p1,”123456789”);
p2=alloc(5);
strcpy(p2,”abcd”);printf(“buf=%p\n”,buf);printf(“p1=%p\n”,p1);printf(“p2=%p\n”,p2);
puts(p1);puts(p2);for(i=0;i<15;i++)printf(“%c”,buf[i]);}例:voidmain()14buf[0]buf[1]::buf[9]buf[10]:buf[14]buf[15]::buf[99]bufpbuf+10p1p2mainbeginnallocbufbufbuf+1012:9\0a:\010buf+15beginnallocbuf+105buf[0]bufpbuf+10p1p2mainbeg15函數(shù)的指針:函數(shù)的入口地址在程序執(zhí)行過(guò)程中調(diào)用函數(shù)時(shí),計(jì)算機(jī)會(huì)轉(zhuǎn)去執(zhí)行函數(shù)體內(nèi)的語(yǔ)句,因此計(jì)算機(jī)必須知道函數(shù)在什么地方。實(shí)際上函數(shù)在內(nèi)存中也要占據(jù)一片存儲(chǔ)單元,這片存儲(chǔ)單元一個(gè)起始地址,我們稱其為函數(shù)的入口地址,即函數(shù)的指針,這個(gè)函數(shù)的入口地址是用函數(shù)名來(lái)表示。因此我們可以定義一個(gè)指針變量,讓它的值等于函數(shù)的入口地址,然后可以通過(guò)這個(gè)指針變量來(lái)調(diào)用函數(shù),該指針變量稱為指向函數(shù)的指針變量三、指向函數(shù)的指針函數(shù)的指針:函數(shù)的入口地址三、指向函數(shù)的指針16指向函數(shù)的指針變量
1.定義格式:數(shù)據(jù)類型(*指針變量名)(形參表列);
int(*pt)(intarr[],intn);
說(shuō)明:①數(shù)據(jù)類型:指針變量所指向的函數(shù)的返回值類型②形參表列:即指針變量所指向的函數(shù)的形參表列③格式中的小括號(hào)不能省略2.應(yīng)用
(1)讓指針變量指向函數(shù)
pt=add;
因?yàn)楹瘮?shù)名為函數(shù)的入口地址,所以直接將函數(shù)名賦給指針變量即可
(2)使用指針變量調(diào)用函數(shù)
格式:
(*指針變量名)(實(shí)參表列)指向函數(shù)的指針變量2.應(yīng)用17例求一維數(shù)組中全部元素的和#include<stdio.h>intadd(intb[],intn);voidmain(){inta[6]={1,3,5,7,9,11},total;
int(*pt)(intb[],intn);
pt=add;
total=(*pt)(a,6);printf(“total=%d\n”,total);}intadd(intb[],intn){inti,sum=0;for(i=0;i<n;i++)sum=sum+b[i];return(sum);}
定義指向函數(shù)的指針變量令指針變量pt指向函數(shù)add通過(guò)pt調(diào)用函數(shù)add例求一維數(shù)組中全部元素的和定義指向函數(shù)令指針變量pt186.3指針與數(shù)組
一.一維數(shù)組與指針
1.一維數(shù)組及元素的地址表示
inta[5]={1,2,3,4,5};
數(shù)組的地址:a
元素
地址*aa[0]&a[0]a*(a+1)a[1]&a[1]a+1*(a+2)a[2]&a[2]a+2*(a+3)a[3]&a[3]a+3*(a+4)a[4]&a[4]a+46.3指針與數(shù)組一.一維數(shù)組與指針元192.用指針變量引用數(shù)組元素(1)定義指針變量
int*p,a[5]={1,2,3,4,5};
p=a;(2)引用數(shù)組元素
下標(biāo)法
地址法
指針?lè)ǖ趉個(gè)元素
a[k]*(a+k)*(p+k)第k個(gè)元素的地址
&a[k]a+kp+k
注意:指針變量也可以加下標(biāo)p[k]等價(jià)于a[k]①分別用三種方法輸出數(shù)組元素,其效率不同,
下標(biāo)法與地址法的效率相同,指針?lè)ǖ男瘦^快②用指針變量訪問(wèn)數(shù)組元素時(shí)要注意下標(biāo)是否越界2.用指針變量引用數(shù)組元素(2)引用數(shù)組元素下標(biāo)法地20
例:將數(shù)組a中全部元素加1,再輸出a#include<stdio.h>voidmain(){inta[5]={1,3,5,7,9},*p,j;for(p=a;p<a+5;p++)printf(“%3d”,*p);printf(“\n”);for(j=0;j<5;j++)a[j]=a[j]+1;for(j=0;j<5;j++)printf(“%3d”,*(p+j));printf(“\n”);}
p=a;13579aa+1a+2a+3a+4246810p可以用p++,但不能用a++因?yàn)閍代表數(shù)組的起始地址它是地址常量,不能改變而p是一個(gè)指針變量使用指針變量時(shí)要注意它的當(dāng)前值例:將數(shù)組a中全部元素加1,再輸出ap=a;1213.指向數(shù)組的指針變量作函數(shù)參數(shù)例6.7①實(shí)參和形參都用數(shù)組名#include<stdio.h>voidinv1(intx[],intn){inttemp,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i;temp=x[i];x[i]=x[j];x[j]=temp;}}voidmain(){inti,a[6]={1,3,4,6,7,9};
inv1(a,6);for(i=0;i<6;i++)printf(“%3d”,a[i]);printf(“\n”);}a[0]a[1]a[2]a[3]a[4]a[5]x[0]x[1]x[2]x[3]x[4]x[5]134679976431maininv13.指向數(shù)組的指針變量作函數(shù)參數(shù)例6.7①實(shí)參和形22例6.7②實(shí)參用數(shù)組名,形參用指針變量#include<stdio.h>voidinv2(int*x,intn){inttemp,m=(n-1)/2;int*p,*i,*j;i=x;j=x+n-1;p=x+m;for(;i<=p;i++,j--){temp=*i;*i=*j;*j=temp;}}voidmain(){inti,a[6]={1,3,4,6,7,9};
inv2(a,6);for(i=0;i<6;i++)printf(“%3d”,a[i]);printf(“\n”);}134679a[0]a[1]a[2]a[3]a[4]a[5]axai6na+5ja+2pinv29173642mtemp1a+1a+4a+2a+334i和j的指向會(huì)變化,p的指向保持不變例6.7②實(shí)參用數(shù)組名,形參用指針變量134679a23例6.7
③實(shí)參和形參都用指針變量#include<stdio.h>voidinv3(int*x,intn);voidmain(){int*p,a[6]={1,3,4,6,7,9};
p=a;
inv3(p,6);for(p=a;p<a+6;p++)printf(“%3d”,*p);printf(“\n”);}voidinv3(int*x,intn){inttemp,m=(n-1)/2;int*p,*i,*j;i=x;j=x+n-1;p=x+m;for(;i<=p;i++,j--){temp=*i;*i=*j;*j=temp;}}例6.7
④實(shí)參用指針變量,形參用數(shù)組名#include<stdio.h>voidinv4(intx[],intn);voidmain(){int*p,a[6]={1,3,4,6,7,9};p=a;inv4(p,6);for(p=a;p<a+6;p++)printf(“%3d”,*p);printf(“\n”);}voidinv4(intx[],intn){inttemp,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i;temp=x[i];x[i]=x[j];x[j]=temp;}}例6.7③實(shí)參和形參都用指針變量例6.7④實(shí)參用指針變24例6.8求數(shù)組中最大和最小元素#include<stdio.h>intmax,min;voidm1(intarr[],intn){int*p,*end;
end=arr+n;max=min=*arr;for(p=arr+1;p<end;p++)if(*p>max)max=*p;elseif(*p<min)min=*p;}voidmain(){inti,a[6];for(i=0;i<6;i++)scanf(“%d”,&a[i]);
m1(a,6);printf(“max=%d,min=%d\n”,max,min);}a[0]a[1]a[2]a[3]a[4]a[5]6narr+1parr+6endmaxmin471905aarr447910例6.8求數(shù)組中最大和最小元素a[0]6narr+1p25二、二維數(shù)組與指針二維數(shù)組的定義a[0]a[1]a[2]a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]對(duì)于二維數(shù)組a,首先可以把它先理解為一個(gè)一維數(shù)組,它有3個(gè)元素:a[0],a[1],a[2]而每一個(gè)元素又是一個(gè)一維數(shù)組,包含4個(gè)元素如a[0]是一維數(shù)組,它有4個(gè)元素:a[0][0],a[0][1],a[0][2],a[0][3]a[3][4]a[0],a[1],a[2]只是一種地址表示方法,并不真的二維數(shù)組元素,可以看作是第二重一維數(shù)組的名字。二、二維數(shù)組與指針二維數(shù)組的定義a[0]a[1]a[2]a[26二維數(shù)組的初始化(1)可以分行給二維數(shù)組賦初值inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};1 2 3 45 6 7 89 10 11 12(2)可以將所有數(shù)據(jù)寫在一個(gè)花括號(hào)中,按順序?qū)Ω髟刭x初值inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};二維數(shù)組的初始化(1)可以分行給二維數(shù)組賦初值int27二維數(shù)組的初始化(3)可以對(duì)部分元素賦初值,其余元素補(bǔ)0inta[3][4]={{1},{5},{9}};1 5 9 inta[3][4]={{1},{0,6},{0,0,11}};1 0 6 0 0 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0二維數(shù)組的初始化(3)可以對(duì)部分元素賦初值,其余元素補(bǔ)028(4)如果對(duì)全部數(shù)據(jù)都賦初值,則定義時(shí)第一維的長(zhǎng)度可以不指定,但第二維的長(zhǎng)度不能省inta[][4]={1,2,3,4,5,6,7,8,9,10,11,12};二維數(shù)組的初始化
如果只對(duì)部分?jǐn)?shù)據(jù)賦初值,第一維的長(zhǎng)度也可以不指定,但元素必須分行賦初值inta[][4]={{0,0,3},{},{0,10}};0 0 3 00 0 0 00 10 0 0(4)如果對(duì)全部數(shù)據(jù)都賦初值,則定義時(shí)第一維的長(zhǎng)度可以不29二維數(shù)組的地址a[0]a[1]a[2]二維數(shù)組名a表示二維數(shù)組的首地址,
也是第0個(gè)元素(a[0])的地址a,&a[0]a+1,&a[1]a+2,&a[2]a+1代表第1個(gè)元素(a[1])的地址a+1
&a[1]a+2代表第2個(gè)元素(a[2])的地址a+2
&a[2]a
&a[0]二維數(shù)組的地址a[030a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a,&a[0]a+1,&a[1]a+2,&a[2]a[0],a[1],a[2]既然是第二重一維數(shù)組名,它們就代表了相應(yīng)一維數(shù)組的首地址,因此a[0]代表了第0行第0列元素的地址,即二維數(shù)組的地址a[1]
&a[1][0]a[1]+2
&a[1][2]a[2]&a[2][0]a[2]+3&a[2][3]a[0]&a[0][0]a[0]+1&a[0][1]a[2]
&a[2][0]a[2]+3
&a[2][3]a[1]+2&a[1][2]a[1]&a[1][0]a[0]
&a[0][0]a[0]+1
&a[0][1]a[0][0]a[0][1]a[0][2]a[0][3]a[31Question*a,*a+1,*(a+1),*(a+2)+3分別表示什么值?a[2][3]a[2][2]a[2][1]a[2][0]a[1][3]a[1][2]a[1][1]a[1][0]a[0][3]a[0][2]a[0][1]a[0][0]Question*a,*a+1,*(a+1),*(a+32二維數(shù)組的地址a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a,&a[0]a+1,&a[1]a+2,&a[2]*(a+2)+3a[2]+3&a[2][3]因a
&a[0]
所以*a
*(&a[0])a[0]
&a[0][0]即*a表示元素a[0][0]的地址a[0]&a[0][0]*a*a+1表示元素a[0][1]的地址*(a+1)表示元素a[1][0]的地址*(a+2)+3表示元素a[2][3]的地址*(a+1)a[1]&a[1][0]*a+1a[0]+1&a[0][1]二維數(shù)組的地址a[0][0]a[0][1]a[0][2]a[33二維數(shù)組的地址小結(jié):二維數(shù)組名a代表二維數(shù)組的首地址,
即:第0行的地址為a
&a[0]第1行的地址為a+1
&a[1]第2行的地址為a+2
&a[2]二維數(shù)組元素的地址a[2][3]a[1][2]a[1][0]a[0][1]a[0][0]元素&a[2][3]&a[1][2]&a[1][0]&a[0][1]&a[0][0]地址a[2]+3a[1]+2a[1]a[0]+1a[0]地址*(a[2]+3)*(a[1]+2)*a[1]*(a[0]+1)*a[0]元素*(a+2)+3*(a+1)+2*(a+1)*a+1*a地址*(*(a+2)+3)*(*(a+1)+2)*(*(a+1))*(*a+1)**a元素二維數(shù)組的地址小結(jié):二維數(shù)組名a代表二維數(shù)組的首地址,第1行34指向二維數(shù)組元素的指針例1:用指針變量輸出二維數(shù)組中的元素Quizp=a;p=&a[0][0];p=*a;p=*a[0];#include<stdio.h>voidmain(){inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int*p;}for(p=a[0];
p<a[0]+12;p++)printf(“%d”,*p);printf(“\n”);指向二維數(shù)組元素的指針例1:用指針變量輸出二維數(shù)組中的元素Q352026q指向二維數(shù)組元素的指針inta[3][4];int**p;p=a;合法嗎?intx=36,*q,**p;q=&x;p=&q;362010x2048p20102026a[0]a[1]a[2]p是二級(jí)指針,它指向一個(gè)整型指針變量q,而q指向一個(gè)整型變量a是一種地址表示方法,a實(shí)際指向了第一重一維數(shù)組元素a[0],而a[0]是第二重一維數(shù)組aa[0][0]a[0][1]a[0][2]a[0][3]非法!2026q指向二維數(shù)組元素的指針inta[3][4];i36指向二維數(shù)組元素的指針
定義格式:類型名(*指針變量名)[數(shù)組長(zhǎng)度];inta[3][4];int(*p)[4];p=a;p指向一個(gè)包含有4個(gè)整型數(shù)據(jù)的一維數(shù)組合法!
雖然在定義p的時(shí)候只用了一個(gè)*,但p實(shí)際上是一個(gè)二級(jí)指針變量指向二維數(shù)組元素的指針定義格式:類型名(*指針變量名)37指向二維數(shù)組元素的指針例2:輸出二維數(shù)組中的元素#include<stdio.h>voidmain(){inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int(*p)[4],i,j;p=a;for(i=0;i<3;i++){for(j=0;j<4;j++)printf(“%6d”,*(*(p+i)+j));printf(“\n”);
}}指向二維數(shù)組元素的指針例2:輸出二維數(shù)組中的元素#inclu38指向二維數(shù)組元素的指針二維數(shù)組用得較多的是“字符串?dāng)?shù)組”,配合字符串的操作,使字符串處理更加方便、靈活。chara[4][256]={"Pascal","VC","Basic","Java"};a[0]a[1]a[2]a[3]Pas
ca
lVcBas
i
cJ
ava\0\0\0\0指向二維數(shù)組元素的指針二維數(shù)組用得較多的是“字符串?dāng)?shù)組”,配39#include<stdio.h>#include<string.h>#defineMAXLEN256#defineN4voidmain(){inti,j;
chartemp[MAXLEN];
charname[N][MAXLEN]={"Pascal","VC","Basic","Java"};
for(i=0;i<N;i++)
puts(name[i]);}//書的數(shù)量for(i=0;i<N-1;i++)for(j=i+1;j<N;j++)
if(strcmp(name[i],name[j])>0){
strcpy(temp,name[i]);
strcpy(name[i],name[j]);
strcpy(name[j],temp);}選擇法排序//書名的最大長(zhǎng)度+1指向二維數(shù)組元素的指針比較兩個(gè)字符串大小復(fù)制字符串Quiz選擇法排序#include<stdio.h>//書的數(shù)量for(i=040Assignment1、將數(shù)組a[2][3]中的每個(gè)元素向右移一列,最后一列換到最左一列(如右圖所示)要求:必須用指針實(shí)現(xiàn)321654=a2135462、將數(shù)組a[M][N]中的每個(gè)元素向右移一列,最后一列換到最左一列要求:必須用指針實(shí)現(xiàn)Assignment1、將數(shù)組a[2][3]中的每個(gè)元素向右41Experiment實(shí)驗(yàn)題目:指向二維數(shù)組的指針編程實(shí)驗(yàn)?zāi)康模荷钊肜斫馊绾斡弥羔樧兞勘硎径S數(shù)組的元素和元素的地址,學(xué)會(huì)用指向二維數(shù)組的指針變量作函數(shù)參數(shù)實(shí)驗(yàn)內(nèi)容:編程找出二維數(shù)組中的鞍點(diǎn),二維數(shù)組的鞍點(diǎn)是指在該位置上的元素在該行上最大,在該列上最小,也可能沒(méi)有鞍點(diǎn)。要求必須用指針實(shí)現(xiàn)。編寫一個(gè)找鞍點(diǎn)的函數(shù),用指向二維數(shù)組的指針變量作函數(shù)參數(shù)Experiment實(shí)驗(yàn)題目:指向二維數(shù)組的指針編程426.4指針與字符串一、字符指針
1.定義指向字符串的指針變量
char*p=“China”;
說(shuō)明:這里沒(méi)有定義字符數(shù)組,但字符串在內(nèi)存中還是以數(shù)組形式存放的.字符串在內(nèi)存中占有一片連續(xù)的存儲(chǔ)單元,以‘\0’結(jié)束
注意:賦值只是把字符串的首地址賦給p,而不是把字符串賦給p,p是一個(gè)指針變量,它不能存放一個(gè)字符串,只能存放一個(gè)地址China\02460246124622463246424652460p
將字符串的首地址賦給p6.4指針與字符串一、字符指針注意:賦值只是把字符串432.輸出字符串:
printf(“%s\n”,p);
輸出字符串時(shí),先輸出p指向的第一個(gè)字符,然后系統(tǒng)自動(dòng)執(zhí)行p++,使p指向下一個(gè)字符,再輸出該字符,直到遇到‘\0’為止也可以用循環(huán)逐個(gè)輸出字符串中的字符:
for(;*p!=‘\0’;p++)printf(“%c”,*p);
China\02460246124622463246424652460p24612462246324642465二、字符數(shù)組與字符指針變量的區(qū)別
chars[]=“CLanguage”;char*p=“CLanguage”;1.存儲(chǔ)方式不同:s存放的是字符串中的字符和‘\0’p存放的是字符串的首地址2.輸出字符串:China\024602460p442.雖然s和p都能代表字符串的首地址,但s是數(shù)組名,
是一個(gè)常量,而p是一個(gè)指針變量,
因此s++的寫法是錯(cuò)的,而p++的寫法是對(duì)的char*p1,*p2=“abcd”;p1=“China”;chars[12],str[]=“good”;s[12]=“China”;s=“China”;3.賦值方式不同
s可以進(jìn)行初始化,
但不能使用賦值語(yǔ)句p既可以初始化,也可以賦值錯(cuò)4.定義數(shù)組s時(shí),系統(tǒng)會(huì)給s分配一片連續(xù)的存儲(chǔ)單元定義指針變量p時(shí),只給p分配一個(gè)存儲(chǔ)單元2.雖然s和p都能代表字符串的首地址,但s是數(shù)組名,45三、字符串指針作函數(shù)參數(shù)例6.20實(shí)現(xiàn)字符串復(fù)制①voidcopystr(charfrom[],charto[]){inti=0;while(from[i]!=‘\0’){to[i]=from[i];
i++;
}
to[i]=‘\0’;}voidmani(){chara[]=“cat”,b[]=“tiger”;puts(a);puts(b);
copystr(a,b);puts(a);puts(b);}cat\0tiger\0abfromatobcat\0相當(dāng)于b[i]=a[i]三、字符串指針作函數(shù)參數(shù)例6.20實(shí)現(xiàn)字符串復(fù)制①ca46例6.20②voidcopystr(char*from,char*to){for(;*from!=‘\0’;from++,to++)
*to=*from;
*to=‘\0’;}voidmain(){char*a=“cat”,*b=“tiger”;puts(a);puts(b);copystr(a,b);puts(a);puts(b);}cat\0tiger\0abfromatobcat\0a+1b+1a+2b+2a+3b+3例6.20②cat\0tiger\0abfromato47第6章指針6.1指針定義與使用6.2指針與函數(shù)6.3指針與數(shù)組6.4指針與字符串6.5指針數(shù)組與多級(jí)指針6.6指針與動(dòng)態(tài)內(nèi)存分配6.7指針的深層應(yīng)用第6章指針6.1指針定義與使用486.1指針的引出一.地址與指針
1.地址與取地址運(yùn)算
C程序中的變量在內(nèi)存中占有一個(gè)可標(biāo)識(shí)的存儲(chǔ)區(qū),
每一個(gè)存儲(chǔ)區(qū)是由若干個(gè)字節(jié)組成,每一個(gè)字節(jié)都有自己的地址,而一個(gè)存儲(chǔ)區(qū)的地址是指該存儲(chǔ)區(qū)中第一個(gè)字節(jié)的地址C語(yǔ)言允許在程序中使用變量的地址(通過(guò)地址運(yùn)算符&可得到)
如:floatx;
變量x的地址----&x
inta[10];
數(shù)組變量a的地址----數(shù)組名a
6.1指針的引出一.地址與指針C語(yǔ)言允許在程序中使用變492.指針與指針變量(1)變量的訪問(wèn)方式①直接訪問(wèn):通過(guò)變量名或地址訪問(wèn)變量的存儲(chǔ)區(qū)
例:scanf(“%d”,&x);
x=sqrt(x);printf(“%d”,x);②間接訪問(wèn):將一個(gè)變量的地址存放在另一個(gè)變量中.
如將變量x的地址存放在變量p中,訪問(wèn)x時(shí)先找到p,
再由p中存放的地址找到xpx201210101010(2)指針:一個(gè)變量的指針就是該變量的地址(指針就是地址)(3)指針變量:存放變量地址的變量,它用來(lái)指向另一個(gè)變量2.指針與指針變量②間接訪問(wèn):將一個(gè)變量的地址存放在50
二、指針變量的定義1.格式:數(shù)據(jù)類型
*指針變量名;
例int*p1;char*p2;2.說(shuō)明:(1)在變量定義時(shí),*號(hào)表示該變量是指針變量
(注意:指針變量是p1,p2,不是*p1,*p2)(2)定義指針變量后,系統(tǒng)為其分配存儲(chǔ)空間,用以存放其他變量的地址,但在對(duì)指針變量賦值前,它并沒(méi)有確定的值,也不指向一個(gè)確定的變量例:intx,*p;x=5;px2012101051234注:指針變量p的值是隨機(jī)值,
此時(shí)p和x并無(wú)關(guān)聯(lián)二、指針變量的定義2.說(shuō)明:例:intx51(3)使指針變量指向一個(gè)確定的變量必須進(jìn)行賦值intx,*p;x=5;p=&x;px2012101051010三、指針變量的引用1.指針運(yùn)算符*(1)p與*p不同,p是指針變量,p的值是p所指向的變量的地址*p是p所指向的變量,*p的值是p所指向的變量的值*p的值為5(*p表示x),而p的值為1010(2)引用指針變量時(shí)的*與定義指針變量時(shí)的*不同定義變量時(shí)的*只是表示其后的變量是指針變量
(3)使指針變量指向一個(gè)確定的變量必須進(jìn)行賦值52inta,*p;p=&a;
scanf(“%d”,p);printf(“%d\n”,*p);*p=12;
printf(“%d\n”,*p);pa201210105101012讓p指向a
對(duì)a重新賦值等價(jià)于a=12
即&a2.&與*
p=&a;
*&a*(&a)*pa&*p&(*p)&ainta,*p;pa2012101051532abcd53.*與++,--inta=2,b=5,c,d,*p;p的值為a的地址,*p的值為2p的值不變,*p的值為3(2)c=*p++;
c=*(p++);{c=*p;p++;}
執(zhí)行后c的值為3,*p的值為5(3)d=*++p;
d=*(++p);{++p;d=*p;}
執(zhí)行后d的值為3,*p的值為3p201210101010(1)p=&a;(*p)++;(等價(jià)于
a++;)101233101432a53.*與++,--p的值54例6.2#include<stdio.h>voidmain(){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”,a,b);printf(“max=%d,min=%d\n”,*p1,*p2);}abp1p2p&a&b&a&b&a59輸出結(jié)果:a=5,b=9max=9,min=5例6.2abp1p2p&a&b&a&b&a59輸出結(jié)果:55一、指針變量作函數(shù)參數(shù)例:2個(gè)數(shù)按大小順序輸出#include<stdio.h>voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}voidmain(){inta,b;scanf(“%d%d”,&a,&b);if(a<b)swap(a,b);printf(“a=%d,b=%d\n”,a,b);}abxytemp5說(shuō)明:該程序不能實(shí)現(xiàn)a和b的交換因?yàn)閷?shí)參a,b
對(duì)形參x,y
是“值傳遞”,x和y
的變化不影響a和b
所以輸出為:a=5,b=99mainswap559956.2指針與函數(shù)一、指針變量作函數(shù)參數(shù)例:2個(gè)數(shù)按大小順序輸出abxyt56例6.3①#include<stdio.h>voidswap1(int*p1,int*p2){inttemp;
temp=*p1;*p1=*p2;*p2=temp;}voidmain(){inta,b,*pt1,*pt2;scanf(“%d%d”,&a,&b);pt1=&a;pt2=&b;if(a<b)swap1(pt1,pt2);printf(“a=%d,b=%d\n”,a,b);}abp1p2temp&b&apt1pt25說(shuō)明:這種方法是交換p1和p2所指向的變量的值,即交換main函數(shù)中a和b的值所以輸出為:a=9,b=5mainswap159&a&b95例6.3①abp1p2temp&b&apt1pt25說(shuō)57例6.3②#include<stdio.h>voidswap2(int*p1,int*p2){int*temp;
*temp=*p1;*p1=*p2;*p2=*temp;}說(shuō)明:這種方法可能會(huì)破壞系統(tǒng)的正常工作狀態(tài),因?yàn)閠emp是一個(gè)指針變量但是在函數(shù)中并沒(méi)有給temp一個(gè)確定的地址,這樣它所指向的內(nèi)存單元是不可預(yù)見(jiàn)的,而對(duì)*temp的賦值可能帶來(lái)危害abpt1pt2main&a&bp1p2temp&b&aswap2?隨機(jī)值55959例6.3②說(shuō)明:這種方法可能會(huì)破壞系統(tǒng)的正常abpt58例6.3③#include<stdio.h>voidswap3(int*p1,int*p2){int*p;
p=p1;p1=p2;p2=p;}p1p2p&a&a&b這種方法是交換形參p1和p2的值,使它們的指向發(fā)生改變,但是main函數(shù)中的a和b的值并沒(méi)有進(jìn)行交換所以輸出為:a=5,b=95a9b&apt1&bpt2main&b&aswap3例6.3③p1p2p&a&a&b這種方法是交換形參p159
前面我們用到的函數(shù),有些無(wú)返回值,有些有返回值,返回值類型多為int,float,char.一個(gè)函數(shù)的返回值也可以是一個(gè)指針類型的數(shù)據(jù)(即地址)定義函數(shù):數(shù)據(jù)類型
*函數(shù)名(形參表列)
{函數(shù)體;}
例:int*fun(inta,intb){函數(shù)體;}
說(shuō)明:定義一個(gè)返回指針值的函數(shù)與以前定義函數(shù)格式基本類似,只是在函數(shù)名前加*
,它表明該函數(shù)返回一個(gè)指針值,而這個(gè)指針值是指向一個(gè)int型數(shù)據(jù)二、函數(shù)返回指針前面我們用到的函數(shù),有些無(wú)返回值,有些有60例:#include<stdio.h>#include<string.h>#defineSIZE100charbuf[SIZE];char*p=buf;char*alloc(intn){char*begin;if(p+n<=buf+SIZE){begin=p;
p=p+n;
return(begin);}elsereturn(NULL);}voidmain(){char*p1,*p2;inti;
p1=alloc(10);
strcpy(p1,”123456789”);
p2=alloc(5);
strcpy(p2,”abcd”);printf(“buf=%p\n”,buf);printf(“p1=%p\n”,p1);printf(“p2=%p\n”,p2);
puts(p1);puts(p2);for(i=0;i<15;i++)printf(“%c”,buf[i]);}例:voidmain()61buf[0]buf[1]::buf[9]buf[10]:buf[14]buf[15]::buf[99]bufpbuf+10p1p2mainbeginnallocbufbufbuf+1012:9\0a:\010buf+15beginnallocbuf+105buf[0]bufpbuf+10p1p2mainbeg62函數(shù)的指針:函數(shù)的入口地址在程序執(zhí)行過(guò)程中調(diào)用函數(shù)時(shí),計(jì)算機(jī)會(huì)轉(zhuǎn)去執(zhí)行函數(shù)體內(nèi)的語(yǔ)句,因此計(jì)算機(jī)必須知道函數(shù)在什么地方。實(shí)際上函數(shù)在內(nèi)存中也要占據(jù)一片存儲(chǔ)單元,這片存儲(chǔ)單元一個(gè)起始地址,我們稱其為函數(shù)的入口地址,即函數(shù)的指針,這個(gè)函數(shù)的入口地址是用函數(shù)名來(lái)表示。因此我們可以定義一個(gè)指針變量,讓它的值等于函數(shù)的入口地址,然后可以通過(guò)這個(gè)指針變量來(lái)調(diào)用函數(shù),該指針變量稱為指向函數(shù)的指針變量三、指向函數(shù)的指針函數(shù)的指針:函數(shù)的入口地址三、指向函數(shù)的指針63指向函數(shù)的指針變量
1.定義格式:數(shù)據(jù)類型(*指針變量名)(形參表列);
int(*pt)(intarr[],intn);
說(shuō)明:①數(shù)據(jù)類型:指針變量所指向的函數(shù)的返回值類型②形參表列:即指針變量所指向的函數(shù)的形參表列③格式中的小括號(hào)不能省略2.應(yīng)用
(1)讓指針變量指向函數(shù)
pt=add;
因?yàn)楹瘮?shù)名為函數(shù)的入口地址,所以直接將函數(shù)名賦給指針變量即可
(2)使用指針變量調(diào)用函數(shù)
格式:
(*指針變量名)(實(shí)參表列)指向函數(shù)的指針變量2.應(yīng)用64例求一維數(shù)組中全部元素的和#include<stdio.h>intadd(intb[],intn);voidmain(){inta[6]={1,3,5,7,9,11},total;
int(*pt)(intb[],intn);
pt=add;
total=(*pt)(a,6);printf(“total=%d\n”,total);}intadd(intb[],intn){inti,sum=0;for(i=0;i<n;i++)sum=sum+b[i];return(sum);}
定義指向函數(shù)的指針變量令指針變量pt指向函數(shù)add通過(guò)pt調(diào)用函數(shù)add例求一維數(shù)組中全部元素的和定義指向函數(shù)令指針變量pt656.3指針與數(shù)組
一.一維數(shù)組與指針
1.一維數(shù)組及元素的地址表示
inta[5]={1,2,3,4,5};
數(shù)組的地址:a
元素
地址*aa[0]&a[0]a*(a+1)a[1]&a[1]a+1*(a+2)a[2]&a[2]a+2*(a+3)a[3]&a[3]a+3*(a+4)a[4]&a[4]a+46.3指針與數(shù)組一.一維數(shù)組與指針元662.用指針變量引用數(shù)組元素(1)定義指針變量
int*p,a[5]={1,2,3,4,5};
p=a;(2)引用數(shù)組元素
下標(biāo)法
地址法
指針?lè)ǖ趉個(gè)元素
a[k]*(a+k)*(p+k)第k個(gè)元素的地址
&a[k]a+kp+k
注意:指針變量也可以加下標(biāo)p[k]等價(jià)于a[k]①分別用三種方法輸出數(shù)組元素,其效率不同,
下標(biāo)法與地址法的效率相同,指針?lè)ǖ男瘦^快②用指針變量訪問(wèn)數(shù)組元素時(shí)要注意下標(biāo)是否越界2.用指針變量引用數(shù)組元素(2)引用數(shù)組元素下標(biāo)法地67
例:將數(shù)組a中全部元素加1,再輸出a#include<stdio.h>voidmain(){inta[5]={1,3,5,7,9},*p,j;for(p=a;p<a+5;p++)printf(“%3d”,*p);printf(“\n”);for(j=0;j<5;j++)a[j]=a[j]+1;for(j=0;j<5;j++)printf(“%3d”,*(p+j));printf(“\n”);}
p=a;13579aa+1a+2a+3a+4246810p可以用p++,但不能用a++因?yàn)閍代表數(shù)組的起始地址它是地址常量,不能改變而p是一個(gè)指針變量使用指針變量時(shí)要注意它的當(dāng)前值例:將數(shù)組a中全部元素加1,再輸出ap=a;1683.指向數(shù)組的指針變量作函數(shù)參數(shù)例6.7①實(shí)參和形參都用數(shù)組名#include<stdio.h>voidinv1(intx[],intn){inttemp,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i;temp=x[i];x[i]=x[j];x[j]=temp;}}voidmain(){inti,a[6]={1,3,4,6,7,9};
inv1(a,6);for(i=0;i<6;i++)printf(“%3d”,a[i]);printf(“\n”);}a[0]a[1]a[2]a[3]a[4]a[5]x[0]x[1]x[2]x[3]x[4]x[5]134679976431maininv13.指向數(shù)組的指針變量作函數(shù)參數(shù)例6.7①實(shí)參和形69例6.7②實(shí)參用數(shù)組
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度臨時(shí)保安服務(wù)合同-活動(dòng)期間安全保衛(wèi)
- 2025年度知識(shí)產(chǎn)權(quán)質(zhì)押合同終止及質(zhì)權(quán)實(shí)現(xiàn)協(xié)議
- 產(chǎn)品發(fā)布營(yíng)銷策略規(guī)劃
- 影視制作發(fā)行合作框架協(xié)議
- 智能能源管理系統(tǒng)建設(shè)投資協(xié)議
- 家具企業(yè)家具設(shè)計(jì)與制造預(yù)案
- 哈他瑜伽介紹課件:哈他瑜伽-身心平衡的藝術(shù)
- 小學(xué)生心理輔導(dǎo)觀后感
- 網(wǎng)絡(luò)購(gòu)物平臺(tái)合作運(yùn)營(yíng)協(xié)議書
- 娛樂(lè)項(xiàng)目節(jié)目制作授權(quán)協(xié)議
- 運(yùn)動(dòng)療法技術(shù)學(xué)
- 《蜀道難》理解性默寫(帶答案)
- 塔吊租賃(大型機(jī)械)-招標(biāo)文件模板(完整版)2021.5.13
- 護(hù)理學(xué)基礎(chǔ)期末試卷及答案
- IMS攪拌樁施工方案
- 我的家鄉(xiāng)廣西南寧宣傳簡(jiǎn)介
- 變廢為寶-小學(xué)科學(xué)高段活動(dòng)案例
- 證明無(wú)親子關(guān)系證明模板
- 消防工程擬投入主要施工設(shè)備機(jī)具表
- 揚(yáng)塵在線監(jiān)測(cè)聯(lián)動(dòng)霧炮噴淋系統(tǒng)
- 過(guò)渡時(shí)期總路線
評(píng)論
0/150
提交評(píng)論