




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第9章指針本章要點:指針與指針變量的定義指針與數(shù)組的關(guān)系指針與字符串的關(guān)系指針與函數(shù)的關(guān)系指針的應用學習方法建議:
本章內(nèi)容是C語言中最難的部分,學習時應注意歸納,重點掌握指針、指針變量的定義,理解指針與數(shù)組、指針與字符串、指針與函數(shù)的關(guān)系,并在此基礎上掌握指針的應用。1.問題描述——尋找保險箱密碼。某國安全局從恐怖分子手中奪取了一個保險箱,保險箱內(nèi)存放了恐怖分子即將發(fā)動的襲擊計劃。于是,上級命令特工008在三天內(nèi)找到保險箱的密碼。008憑著他的機智勇敢,費盡千辛萬苦,終于打聽到密碼可能存放在某健身中心的自動寄存箱內(nèi)??墒堑人搅私∩碇行?,發(fā)現(xiàn)有上千個單元的格子,每個單元格都放有一個寄存箱,上面貼有一個名字,例如“太陽一號”、“月亮二號”等,根本不知道密碼在哪一個單元格中。正在他一籌莫展之時,臥底人員發(fā)來短消息:“速開0217單元的‘虎跑號’寄存箱,內(nèi)詳”。008打開“虎跑號”寄存箱,發(fā)現(xiàn)里面留有一行小字:“在1976單元”。他疾步趕到1976單元,找到了“龍井號”寄存箱,打開箱子,終于得到了密碼“911”,從而粉碎了一場大陰謀,順利完成任務。2.引例分析下面簡單分析一下如何才能尋找到密碼,分為幾種情況。(1)密碼存放在某個寄存箱內(nèi),如果知道這個寄存箱的名字,就能夠找到密碼。(2)如果不知密碼所在的寄存箱名字,知道該寄存箱的地址也照樣能夠取出密碼。(3)如果寄存箱的地址也不知道,但是有另外一個地方存放這個寄存箱的地址,就能順藤摸瓜,間接找到密碼。9.1引例3.程序代碼#include"stdio.h"main(){intkey=911;/*變量key存放密碼*/int*addr;/*變量addr存放地址*/addr=&key;/*變量key的地址存放在變量addr中*//*通過變量key輸出密碼值*/printf("Thekeyis:%d\n",key);/*通過變量key的地址來輸出密碼值*/printf("IfIknowtheaddressofthekey,Ialsocangetit:%d\n",*addr);}9.2.1指針變量的定義1.內(nèi)存地址計算機硬件系統(tǒng)的內(nèi)存儲器中,擁有大量的存儲單元,每個存儲單元的容量為1字節(jié)。為了方便管理,為每一個存儲單元都做了編號,這個編號就是存儲單元的“地址”。內(nèi)存單元的地址與內(nèi)存單元中的數(shù)據(jù)是兩個完全不同的概念。2.變量地址變量標識符、內(nèi)存地址和變量值的關(guān)系如圖9-1所示。9.2指針變量的定義與應用3.指針與指針變量指針即地址。一個變量的地址稱為該變量的指針,通過變量的指針能夠找到該變量。指針變量用于存儲其他變量地址的變量。指針與指針變量的區(qū)別,就是變量值與變量的區(qū)別。指針變量定義為:數(shù)據(jù)類型*指針變量1[,*指針變量2…];例如:intnum=3,*num_pointer=#指針變量num_pointer、變量num與存儲在變量中的值的關(guān)系如圖所示。4.指針運算符(1)取地址運算符&取地址運算符&的格式為:&標識符例如:inta,*pa;/*定義變量a和指針變量pa,且pa指向的數(shù)據(jù)類型為整型*/pa=&a;/*把變量a的地址賦給指針變量pa,指針變量pa就指向了變量a*/(2)間接訪問運算符*間接訪問運算符*的格式為:*地址例如:inta=2,b,*p;p=&a;/*p指向a*/b=*p;/*把p所指向變量a的值賦給變量b*/【例9.1】指針變量的定義與相關(guān)運算示例。#include"stdio.h"voidmain(){inta=12,*pa;/*定義一個指向int型數(shù)據(jù)的指針變量pa*/floatb=3.14,*pb; /*定義一個指向float型數(shù)據(jù)的指針變量pb*/charc='p',*pc;/*定義一個指向char型數(shù)據(jù)的指針變量pc*/pa=&a; /*取變量a的地址,賦值給pa*/pb=&b; /*取變量b的地址,賦值給pb*/pc=&c; /*取變量c的地址,賦值給pc*/printf("a=%d,*pa=%d\n",a,*pa);printf("b=%4.2f,*pb=%4.2f\n",b,*pb);printf("c=%c,*pc=%c\n",c,*pc);} 【例9.2】輸入2個整數(shù),按升序(從小到大排序)輸出。#include"stdio.h"voidmain()
{
intnum1,num2;int*p1=&num1,*p2=&num2,*p;printf("Inputthefirstnumber:");scanf("%d",p1);/*將輸入的第一個數(shù)送入指針p1指向的內(nèi)存空間*/printf("Inputthesecondnumber:");scanf("%d",p2);/*將輸入的第二個數(shù)送入指針p2指向的內(nèi)存空間*/printf("num1=%d,num2=%d\n",num1,num2);if(*p1>*p2)/*如果num1>num2,則交換指針*/{p=p1;p1=p2;p2=p;}printf("min=%d,max=%d\n",*p1,*p2);} 【例9.3】使用函數(shù)調(diào)用方式改寫例9.2,要求實參為指針變量。voidexchange(int*pointer1,int*pointer2){inttemp;
temp=*pointer1,*pointer1=*pointer2,*pointer2=temp;/*交換變量*/}voidmain(){intnum1,num2;int*p1=&num1,*p2=&num2;/*定義并初始化指針變量p1和p2*/scanf("%d%d",p1,p2);printf("num1=%d,num2=%d\n",num1,num2);if(*p1>*p2)exchange(p1,p2);printf("min=%d,max=%d\n",num1,num2);}9.2.2指針變量作函數(shù)參數(shù)【例9.4】輸入3個整數(shù),按降序輸出。#include"stdio.h"voidexchange(int*pointer1,int*pointer2){inttemp;temp=*pointer1,*pointer1=*pointer2,*pointer2=temp;}main(){intnum1,num2,num3;scanf("%d%d%d",&num1,&num2,&num3);if(num1<num2) exchange(&num1,&num2);/*變量的地址作為實參*/if(num1<num3)exchange(&num1,&num3);if(num2<num3)exchange(&num2,&num3);printf("%d,%d,%d\n",num1,num2,num3);/*輸出排序后的的結(jié)果*/}
9.3.1概念C語言規(guī)定數(shù)組名代表數(shù)組的首地址,所以數(shù)組名是一個常量指針,數(shù)組元素的地址可以通過數(shù)組名加偏移量來取得。若定義一個指針變量,使它指向一個數(shù)組,則該指針變量稱為指向數(shù)組的指針變量。例如:intarray[10],*pointer=array;或者:*pointer=&array[0];
或者:intarray[10],*pointer;pointer=array;9.3數(shù)組的指針和指向數(shù)組的指針變量數(shù)組元素的引用,既可用下標法,也可用指針法。使用下標法,直觀。例如:array[0]、array[1]、array[2]…等等。使用指針法,能使目標程序占用內(nèi)存少、運行速度快。例如:array+i、pointer+i等等。如果有“intarray[10],*pointer=array;”,則:pointer+i和array+i都是數(shù)組元素array[i]的地址,*(pointer+i)和*(array+i)就是數(shù)組元素array[i]。指向數(shù)組的指針變量,也可將其看作是數(shù)組名,因而可按下標法來使用。例如:pointer[i]等價于*(pointer+i)。9.3.2一維數(shù)組元素的引用【例9.5】使用指向數(shù)組的指針變量來引用數(shù)組元素。#include"stdio.h"main(){intarray[10],*pointer=array,i;/*定義數(shù)組和指向數(shù)組的指針變量*/printf("Input10numbers:");for(i=0;i<10;i++)scanf("%d",pointer+i);/*使用指針變量來輸入數(shù)組元素的值*/printf("array[10]:");for(i=0;i<10;i++)printf("%3d",*(pointer+i));/*使用指向數(shù)組指針變量輸出數(shù)組*/printf("\n");}1.算術(shù)運算可以進行的算術(shù)運算,只有以下幾種:px±n,px++/++px,px--/--px,px-py注意:px±n:將指針從當前位置向前(+n)或回退(-n)n個數(shù)據(jù)單位,而不是n個字節(jié)。顯然,px++/++px和px--/--px是px±n的特例(n=1)。px-py:兩指針之間的數(shù)據(jù)個數(shù),而不是指針的地址之差。2.關(guān)系運算
px<py,px=py,px>py9.3.3對指向數(shù)組的指針變量進行算術(shù)運算和關(guān)系運算數(shù)組名作形參時,接收實參數(shù)組的起始地址;作實參時,將數(shù)組的起始地址傳遞給形參數(shù)組。引入指向數(shù)組的指針變量后,數(shù)組及指向數(shù)組的指針變量作函數(shù)參數(shù)時,可有四種等價形式:1.實參是數(shù)組名,形參是數(shù)組。main()f(intx[],intn){inta[10];{……}f(a,10)…}2.實參是數(shù)組名,形參是指針變量。main()f(int*x,intn){inta[10];{……f(a,10);}…}3.實參和形參都是指針變量。main()f(int*x,intn){inta[10],*p;{p=a;……}f(p,10);…}4.實參是指針變量,形參是數(shù)組。
main()f(intx[],intn){inta[10],*p;{p=a;……}f(p,10);…}9.3.4數(shù)組作函數(shù)參數(shù)【例9.6】用選擇法對10個整數(shù)按由大到小順序排序。#include"stdio.h"sort(intx[],intn)/*形參為數(shù)組*/{inti,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;}}}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++);}定義一個二維數(shù)組:inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};a是二維數(shù)組數(shù)組名。將a數(shù)組看成3個一維數(shù)組組成。3個一維數(shù)組名分別為a[0],a[1],a[2],每一個一維數(shù)組又包含4個元素,例如:a[0]代表的一維數(shù)組又包含元素a[0][0],a[0][1],a[0][2],a[0][3]。9.3.5二維數(shù)組的指針及其指針變量對于二維數(shù)組inta[3][4],有:a表示:二維數(shù)組的首地址,即第0行的首地址。a+i表示:第i行的首地址。a[i]等價于*(a+i)表示:第i行第0列的元素地址。a[i]+j等價于*(a+i)+j表示:第i行第j列的元素地址。通常把指向行的地址,稱為行指針,指向列的地址,稱為列指針。如果用a作指針訪問二維數(shù)組的元素可表示為:*(a[i]+j)等價于*(*(a+i)+j)等價于a[i][j]如果用指針p作為指向數(shù)組的指針,且有inta[3][4],*p=a[0];則p+1指向下一個元素。用p作指針訪問數(shù)組元素a[i][j]的格式為:*(p+(i*總列數(shù)+j))表9-1數(shù)組a的性質(zhì)表示形式含義a二維數(shù)組名,指向一維數(shù)組a[0],即0行首地址a[0],*(a+0),*a0行0列元素地址a+1,&a[1]1行首地址a[1]+2,*(a+1)+2,&a[1][2]1行2列元素a[1][2]的地址*(a[1]+2),*(*(a+1)+2),a[1][2]1行2列元素a[1][2]的值【例9.7】使用行指針和列指針兩種方式輸出二維數(shù)組任一元素。①使用行指針#include"stdio.h"main(){intarray[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};introw,col,(*pointer)[4]; /*定義行指針變量(*pointer)[4]*/pointer=array;/*使行指針變量指向數(shù)組的起始地址*/printf("Inputrow=");scanf("%d",&row);printf("Inputcol=");scanf("%d",&col);printf("array[%1d][%1d]=%d\n",row,col,*(*(pointer+row)+col));}②使用列指針#include"stdio.h"main(){intarray[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};int*pointer,row,col; /*定義一個列指針變量pointer*/pointer=array[0];/*使列指針變量pointer為0行0列元素地址*/printf("Inputrow=");scanf("%d",&row);printf("Inputcol=");scanf("%d",&col);printf("array[%1d][%1d]=%d\n",row,col,*(pointer+(row*4+col)));}
二維數(shù)組的指針作函數(shù)實參時,有列指針和行指針兩種形式。相應的,用來接受實參數(shù)組指針的形參,必須使用相應形式的指針變量,如下所示:實參:列指針行指針↓↓形參:(列)指針變量行指針變量9.3.6二維數(shù)組指針作函數(shù)參數(shù)1.字符串的表示與引用(1)逐個引用【例9.8】使用字符指針變量表示和引用字符串。#include"stdio.h"main(){char*string="IloveBeijing.";for(;*string!='\0';string++)printf("%c",*string);}9.4字符串的指針和指向字符串的指針變量【例9.9】采取整體引用的辦法,改寫例9.8。#include"stdio.h"main(){char*string="IloveBeijing.";printf("%s\n",string);} 2.字符串指針作函數(shù)參數(shù)【例9.10】用函數(shù)調(diào)用方式,實現(xiàn)字符串的復制。#include"stdio.h"voidstring_copy(char*from,char*to){/*字符指針from接收源串,字符指針to存儲目標串*/inti=0;for(;(*(to+i)=*(from+i))!='\0';i++);/*循環(huán)體為空語句*/}voidmain(){charstr1[20]="Iamateacher.";charstr2[20];string_copy(str1,str2);/*調(diào)用函數(shù),數(shù)組名作實參*/printf("str2:%s\n",str2);}返回指針值的函數(shù)(簡稱指針函數(shù))的定義格式如下:函數(shù)類型*函數(shù)名([形參表])【例9.11鍵盤輸入10個數(shù),調(diào)用函數(shù)求其中的最大值。#include<stdio.h>int*max(int*q,intn)/*max為返回指針值的函數(shù)*/{ inti,*m=q;/*假設最大數(shù)為a[0],m為最大值的指針*/ for(i=1;i<n;i++)if(*(q+i)>*m)m=q+i;/*保留實際最大值的指針*/ returnm;/*返回最大值的指針值*/}voidmain(){inti,a[10],*p;for(i=0;i<10;i++) scanf("%d",&a[i]);p=max(a,10);printf("Max=%d\n",*p);}9.5返回指針值的函數(shù)【例9.12】有若干計算機圖書,請按字母順序,從小到大輸出書名。voidsort(char*name[],intcount){char*temp_p;inti,j,min;/*使用選擇法排序*/for(i=0;i<count-1;i++) /*外循環(huán):控制選擇次數(shù)*/{min=i; /*預置本次最小串的位置*/for(j=i+1;j<count;j++) /*內(nèi)循環(huán):選出本次的最小串*/if(strcmp(name[min],name[j])>0)/*存在更小的串*/min=j; /*保存*/if(min!=i) /*存在更小的串,交換位置*/temp_p=name[i],name[i]=name[min],name[min]=temp_p;}}voidmain(){char*name[5]={"BASIC","FORTRAN","PASCAL","C","FoxBASE"};inti=0;sort(name,5);/*使用字符指針數(shù)組名作實參,調(diào)用排序函數(shù)sort()*/for(;i<5;i++)printf("%s\n",name[i]);/*輸出排序結(jié)果*/}9.6.1指針數(shù)組
數(shù)據(jù)類型*數(shù)組名[元素個數(shù)]【例9.13】定義二級指針。源程序#include"stdio.h"voidmain(){intx=100;int*p1;int**p2;/*定義二級指針*/p1=&x;/*將x的地址給p1*/p2=&p1;/*將p1的地址給p2*/printf(“%d,%d”,*p1,**p2);}9.6指針數(shù)組與主函數(shù)main()的形參主函數(shù)main()的有參形式為:main(intargc,char*argv[]){……}運行帶形參的主函數(shù),必須在操作系統(tǒng)狀態(tài)下,輸入主函數(shù)所在的可執(zhí)行文件名,以及所需的實參,然后回車即可。命令行的一般格式為:可執(zhí)行文件名實參1[實參2……]9.6.2主函數(shù)main()的形參指向指針的指針變量的一般定義格式為:數(shù)據(jù)類型**指針變量1[,**指針變量2……];例如,char**p;【例9.13】定義二級指針#include"stdio.h"main(){intx=100;int*p1;int**p2;/*定義二級指針*/p1=&x;/*將x的地址給p1*/p2=&p1;/*將p1的地址給p2*/printf(“%d,%d”,*p1,**p2);}9.6.3指向指針的指針變量【例9.14】使用二級指針輸出字符串。#include"stdio.h"main(){char*name[]={“China”,“Beijing”,“GreatWall”,“World”};char**p;intj;for(j=0;j<4;j++){ p=name+j;printf(“%s\n”,*p);}}9.7.1指向函數(shù)的指針變量的定義定義指向函數(shù)的指針變量的一般形式為:類型名(*指針變量名)(參數(shù)類型1,參數(shù)類型2…);例如:int(*p)();9.7.2用指向函數(shù)的指針變量調(diào)用函數(shù)一般形式為:(*指針變量名)(實參表)9.7函數(shù)的指針和指向函數(shù)的指針變量簡介【例9.15】求x,y中的較小數(shù)#include"stdio.h"main(){intmin(int,int);int(*p)(int,int),x,y,z;printf("Enterx,y:");scanf("%d%d",&x,&y);p=min;z=(*p)(x,y);printf("Min(%d,%d)=%d\n",x,y,z);
}intmin(inta,intb){returna<b?a:b;}有關(guān)指針的數(shù)據(jù)類型的小結(jié)。9.8指針小結(jié)指針的不同表現(xiàn)方式為:定義含義inti;i:整型變量i。int*p;p:指向整型數(shù)據(jù)的指針變量。inta[N];
a[N]:整型數(shù)組,它有N個元素。int*p[N];p:指針數(shù)組,它由N個指向整型數(shù)據(jù)的指針元素組成。int(*p)[N];p:行指針變量,是每個行含有N個元素的二維數(shù)組的指針。int*p();p:指針函數(shù),該函數(shù)返回一個指向整型數(shù)據(jù)指針。int(*p)();p:函數(shù)指針變量,該函數(shù)指針指向整型數(shù)據(jù)。int**p;p:是一個雙重指針變量,它指向一個指向整型數(shù)據(jù)的指針變量。上機實驗1.掌握指針、指針變量的定義;2.掌握指針的應用方法和注意事項;3.掌握指針與數(shù)組、指針與字符串和指針與函數(shù)的關(guān)系。一、實驗目的1.驗證性實驗1)閱讀下面的程序,并上機運行該程序。#include<stdio.h>fun(char*s){char*p=s;while(*p)p++;return(p-s);}voidmain(){char*a="975321";printf("%d",fun(a));}二、實驗內(nèi)容2)閱讀下面的程序,并上機運行該程序。#include<stdio.h>voidmain(){inta[]={0,1,2,3,4,5,6,7,8,9},s=0,i,*p;p=&a[0];
for(i=0;i<10;i+=2)s+=*(p+i);printf("s=%d",s);}3)閱讀下面的程序,并上機運行該程序。#include<stdio.h>main(){char*a="Iwishyousuccess!";
intk;printf("%c\n",a[7]);
for(k=0;a[k]!='\0';k++)printf("%c",a[k]);}
4)下面給定程序中fun函數(shù)的功能是:分別統(tǒng)計字符串中大寫字母和小寫字母的個數(shù)。請改正程序中的錯誤,使它能計算出正確的結(jié)果。#include<stdio.h>voidfun(char*s,inta,intb){while(*s){if(*s>='A'&&*s<='Z')a++;if(*s>='a'&&*s<='z')b++;s++;}}main(){chars[100];intupper=0,lower=0;printf("\nPleaseastring:");gets(s);
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 值守工作補助方案(3篇)
- 夜市安全經(jīng)濟檢查方案(3篇)
- 蛋白質(zhì)組與蛋白質(zhì)組學
- 一級建造師課件369
- 涉案車輛管理措施方案(3篇)
- 三農(nóng)工作全流程作業(yè)指導書
- 理療店管理裝修方案(3篇)
- 墻體拆除裝修方案(3篇)
- 十年后的我初一滿分作文(10篇)
- 食品應急備貨保障方案(3篇)
- 醫(yī)院綜合門診部綜合管理體系建設
- 陜西省專業(yè)技術(shù)人員繼續(xù)教育2025公需課《黨的二十屆三中全會精神解讀與高質(zhì)量發(fā)展》20學時題庫及答案
- 健美操 單元作業(yè)設計
- 劍橋英語二級全冊詞匯匯總
- 機修鉗工培訓
- 血透室消毒隔離制度課件
- 調(diào)節(jié)閥計算書(帶公式)
- 醫(yī)德醫(yī)風建設培訓課件
- 通信工程竣工資料模板(通用版)
- 中國半導體行業(yè)投資深度分析與展望
- 應急中心組織架構(gòu)
評論
0/150
提交評論