




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
8.1指針的概念一、變量的地址
計算機中,數據存儲在內存中,內存可劃分為若干存儲單元,每個單元可以存放8位二進制數,即1個字節,每個單元具有唯一的一個地址。(內存區的每一個字節有一個編號,即地址)變量的地址:系統為變量分配的內存單元的地址。(一個無符號的整型數)inta;floatb;a=3;b=5;二、變量的訪問方式1)直接訪問2)間接訪問定義一個變量p,存放a的地址,通過p訪問a,若將變量p的值改為3AB8(b的地址),則可通過p訪問b。三、指針變量:存放地址的變量如:p為指針變量,它存放整型變量a的首地址,稱指針變量p指向整型變量a。8.2指針變量的定義與引用一、定義方法類型符*指針變量名如:int*p1,*p2;char*ps;float*pf;指針變量的類型:所指向的內存中存放的數據的類型。二、指針變量的賦值指針變量的值是地址,是個無符號整數。(不能直接將整型常量賦給指針變量)1)用變量的地址給指針變量賦值(求地址運算符&)變量的類型必須與指針變量的類型相同如:inta,b,*p;p=&a;2)用相同類型的指針變量賦值如:inta;int*p1,*p2;p1=&a;p2=p1;3)賦空值NULLp=NULL;或p=0;指針變量初始化方法:賦空值NULL用已定義的變量的地址int*p1=NULL;floata;float*p2=&a;三、指針變量的應用1)兩個運算符:*、&
形式:&任意變量
/*取地址運算符*/
*指針變量
/*指針運算符*/&a表示變量a所占據的內存空間的首地址;*p表示指針變量p所指向的內存中的數據。應用:通過指針變量訪問所指變量將指針變量指向被訪問的變量如:inta=5,*p,b;p=&a;訪問所指變量取內容:b=*p;存內容:*p=100;注意:*p若出現在“=”的右邊或其他表達式中則為取內容;*p若出現在“=”的左邊為存內容。#include<stdio.h>intmain(){inta=5,b=3;int*p;p=&a;b=*p+5;printf(“%d\n”,b);*p=4;printf(“%d,%d”,a,*p);}104,4例:讀程序寫結果。#include<stdio.h>intmain(){inta=3,b=5;int*p=&a;printf(“%d\n”,*p);*p=4;p=&b;printf(“%d\n”,*p);*p=6;printf(“%d,%d\n”,a,b);}354,62)運算規則*、&:優先級相同,且右結合,與++、--、!等單目運算符優先級相同。下列表達式的含義:
&*p*&a等價于pa2)運算規則*、&:優先級相同,且右結合,與++、--、!等單目運算符優先級相同。寫出下面各表達式的結果,并找出具有等價關系的對子。inta=5,*p=&a;&*p*&a(*p)++&aa*p++*(p++)a++下列表達式的含義:
&*p*&a等價于pa#include<stdio.h>intmain(){inta,b,c;int*pa,*pb,*pc;pa=&a,pb=&b,pc=&c;scanf(“%d%d”,pa,pb);c=a+b;printf(“c=%d\n”,*pc);*pc=a+*pb;printf(“c=%d\n”,c);c=++*pa+(*pb)++;printf(“c=%d\n”,c);}例:交換兩個數a、b的值#include<stdio.h>intmain(){inta=5,b=8;intt;printf(“a=%d,b=%d\n”,a,b);t=a;a=b;b=t;printf(“a=%d,b=%d\n”,a,b);}例:交換兩個數a、b的值#include<stdio.h>intmain(){inta=5,b=8;intt;int*pa=&a,*pb=&b;printf(“a=%d,b=%d\n”,a,b);t=*pa;*pa=*pb;*pb=t;printf(“a=%d,b=%d\n”,a,b);}指針變量作函數參數例:編寫一個函數實現兩個數的交換。#include<stdio.h>intswap(intx,inty){intt;t=x;x=y;y=t;}main(){inta=3,b=5;swap(a,b);printf(“%d%d”,a,b);}#include<stdio.h>intswap(int*x,int*y){intt;t=*x;*x=*y;*y=t;}main(){inta=3,b=5;swap(&a,&b);printf(“%d%d”,a,b);}例:輸入a,b,c三個數,按大小順序輸出。#include<stdio.h>intswap(int*x,int*y){intt;t=*x;*x=*y;*y=t;}intmain(){inta,b,c;printf(“enterdataa,b,c:”);scanf(“%d%d%d”,&a,&b,&c);if(a<b)swap(&a,&b);if(a<c)swap(&a,&c);
if(b<c)swap(&b,&c);printf(“%d%d,%d”,a,b,c);}8.3指針和數組一、一維數組與指針1)數組是連續存放的若干個元素的集合2)數組名就是指向此數組第1個元素的指針(首地址)如:inta[10],*p;則p=a;等價于p=&a[0];3)某一元素的地址:p=&a[i]
用指針引用該元素:*pa[i]4)數組元素的下標在內部實現時,統一按“基地址+位移”的方式處理,即:aa+1a+i故表示數組元素的地址可用:p+i、a+i
表示數組元素的內容可用:a[i]、*(p+i)、*(a+i)數組名a(數組的指針)與指向數組首地址的指針變量p不同,a不是變量。例:讀程序寫結果。#include<stdio.h>intmain(){inti,a[5];int*p;for(i=0;i<5;i++){p=&a[i];a[i]=i;printf(“%3d”,*p);}printf(“\n”);}#include<stdio.h>intmain(){inti,a[5];int*p=a;for(i=0;i<5;i++,p++){*p=i;printf(“%3d”,*p);}printf(“\n”);}數組指針、指針變量與數組元素之間的關系:設有inta[10],*p=a;則例:數組的使用intmain(){inti,a[5],*p=a;printf(“Input5numbers:\n”);for(i=0;i<5;i++)scanf(“%d”,&a[i]);printf(“Outputthesenumbers:\n”);for(i=0;i<5;i++)printf(“%d”,a[i]);printf(“\n”);}scanf(“%d”,a+i);scanf(“%d”,p+i);printf(“%d”,*(a+i));printf(“%d”,*(p+i));二、指針的運算1)賦值運算如:p=&x;p=a;p=NULL;2)加減運算如:a+i、p+i(只能用于數組元素的引用,注意下標的有效范圍)3)指針相減運算:求兩地址的間距如:p-a(兩個指針的類型相同,并指向同一連續的存儲區域)4)移動指針(++、--)如:p++
(對數組名不能實施該運算)例:將數組a的數據復制到數組b中并輸出#include<stdio.h>#defineM7intmain(){inti,a[M]={23,15,50,3,21,20,35},b[M];for(i=0;i<M;i++)b[i]=a[i];printf(“Outputthesenumbers:\n”);for(i=0;i<M;i++)printf(“%d”,b[i]);printf(“\n”);}#include<stdio.h>#defineM7intmain(){inti,a[M]={23,15,50,3,21,20,35},b[M];int*p=a,*q=b;for(i=0;i<M;i++){*q=*p;q++;p++;}printf(“Outputthesenumbers:\n”);for(i=0;i<M;i++)printf(“%d”,b[i]);printf(“\n”);}例:將數組a的數據復制到數組b中并輸出#include<stdio.h>#defineM7intmain(){inti,a[M]={23,15,50,3,21,20,35},b[M];for(i=0;i<M;i++)b[i]=a[i];printf(“Outputthesenumbers:\n”);for(i=0;i<M;i++)printf(“%d”,b[i]);printf(“\n”);}#include<stdio.h>#defineM7intmain(){inti,a[M]={23,15,50,3,21,20,35},b[M];int*p=a,*q=b;for(i=0;i<M;i++){*q=*p;q++;p++;}printf(“Outputthesenumbers:\n”);for(i=0;i<M;i++)printf(“%d”,b[i]);printf(“\n”);}printf(“%d”,*q++);三、數組的指針與函數實參例:編寫一函數求一維數組的最大元素及其下標位置(要求使用指針)已知:數組首地址p,元素個數n;(作函數參數)結果:下標k;(作返回值)intmax_array(int*p,intn)設最大值放在max中,則初始狀態為:
max=*p,k=0如果*(p+i)>max則max=*(p+i)且k=i#include<stdio.h>intmax_array(int*p,intn){intk=0,max=*p,i;for(i=0;i<n;i++)if(*(p+i)>max){max=*(p+i);k=i;}returnk;}intmain(){inta[10]={23,43,52,23,5,22,33,35,96,34};inti,*p=a,k;for(i=0;i<10;i++)printf(“%5d”,*(p+i));k=max_array(a,10);printf(“\nmax=a[%d]=%d\n”,k,*(p+k));}例:編寫一函數求一維數組的元素倒置存放。已知:一維數組,元素個數n;結果:倒置后的一維數組函數定義:intinverse(int*p,intn)算法:1、令p指向數組的開始,q指向結束2、交換兩單元的內容3、兩指針向中間靠攏4、重復上述2和3,直到p>=q#include<stdio.h>intinverse(int*p,intn){int*q,t;q=p+n-1;while(p<q){t=*p;*p=*q;*q=t;p++;q--;}}intmain(){inta[]={1,3,5,7,9};intk,*p;for(p=a,k=0;k<5;k++)printf(“%5d”,*p++);printf(“\n”);inverse(a,5);for(p=a,k=0;k<5;k++)printf(“%5d”,*p++);}四、多維數組與指針
用指針變量可以指向一維數組中的元素,也可以指向多維數組中的元素。1.多維數組元素的地址可以認為二維數組是“數組的數組”,例:定義inta[3][4]={{1,3,5,7},{2,4,6,8},{9,1,0,1}};則二維數組a是由3個一維數組所組成的。135724689101a[0]a[1]a[2]a此二維數組可以看作三個一維數組
a為二維數組的首地址
a[0]或*a為第一個一維數組的首地址
a[0][0]或*(*a+0)為第一個一維數組的第一個元素135724689101a[0]a[1]a[2]aa[i][j]*(a[i]+j)*(*(a+i)+j)數組元素
a[i]&a[i][0]*(a+i)數組元素地址a+i&a[i]a是二維數組名,不同于一維數組,如:
staticinta[3][4]={{1,3,5,7},{2,4,6,8},{9,1,0,1}};
int*p;可以p=a[0];而p=a錯誤。不要把&a[i]理解為a[i]單元的物理地址,因為a[i]不是一個變量,&a[i]和a[i]的值是相等的。但含意不一樣。前者指向行,后者指向列;
&a[i]:第i行的首地址a[i]:第i行0列地址
&a[i]+1:第i+1行的首地址a[i]+1:第i行1列的地址表示形式含義a
二維數組名,指向一維數組a[0],即0行首地址a[0],*(a+0),*a0行0列元素地址a+1,&a[1]1行首地址a[1],*(a+1)1行0列元素a[1][0]的地址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]的值2.指向多維數組元素的指針變量(1)指向數組元素的指針變量例:用指針變量輸出二維數組元素的值
#include<stdio.h>intmain(){
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);
}}
運行結果如下:1357911131517192123
(2)指向由m個元素組成的一維數組的指針變量例:出二維數組任一行任一列元素的值#include<stdio.h>intmain(){inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int(*p)[4],i,j;
p=a;
scanf(“i=%d,j=%d”,&i,&j);printf(“a[%d,%d]=%d\n”,i,j,*(*(p+i)+j));}
運行情況如下:i=1,j=2↙a[1,2]=138.4指針與字符串1)C語言中字符串以‘\0’作結束符;2)用字符數組存放字符串;3)字符串指針就是字符數組的首地址。如:chara[]=“Apple”;charb[]={‘C’,’h’,’i’,’n’,’a’,’\0’};一、字符串指針變量定義:char*指針變量如:char*p,*q=“Language”;p=“Thisisabook.”;如:char*p,c[10];p=c;注意:p指向字符串的首地址,不是存放字符串。例:逆序打印字符串算法:設字符串為q;令p指向串尾;打印字符*p,并將p前移,直到p指向串首。#include<stdio.h>intmain(){char*p,*q=“Language”;for(p=q;*p!=‘\0’;)p++;for(p--;p>=q;p--)putchar(*p);putchar(‘\n’);}例:逆序打印字符串算法:設字符串為q;令p指向串尾;打印字符*p,并將p前移,直到p指向串首。#include<stdio.h>intmain(){char*p,*q=“Language”;n=strlen(q);p=q+n;for(p--;p>=q;p--)putchar(*p);putchar(‘\n’);}例:編寫一函數判斷一個字符串是否回文。(順讀與逆讀相同)已知:字符串指針變量p(作參數);結果:是或否算法:1、令q指向最后一個字符2、*p==*q,則兩指針向里靠攏,直到p>=q,則return1;否則return0intishuiwen(char*p){char*q=p;while(*q!=‘\0’)q++;q--;while(p<q)if(*p==*q){p++;q--;}elsereturn0;return1;}三、字符數組與字符指針變量比較
chara[]=“Ilovethisgame”,*p=a;1)存儲的內容不同字符數組可以存字符串,存的是字符;字符指針變量存的是字符串在內存的首地址。2)賦值方式不同字符數組只能對各個元素賦值;字符指針變量只賦值一次,賦的是地址。如:chara[10],*p;p=“China”;a=“Hello”;(錯誤)3)當沒有賦值時字符數組名代表了一個確切的地址;字符指針變量中的地址是不確定的。如:chara[10],*p;scanf(“%s”,a);scanf(“%s”,p);(錯誤)4)字符數組名不是變量,不能改變值;字符指針變量可以改變值。如:a++;(錯誤)p++;8.5指向函數的指針變量
一個函數在編譯時被分配給一個入口地址,這個入口地址就稱為函數的指針。可以定義一個指針變量指向函數,該指針稱為指向函數的指針變量。其定義形式如下:例如:int(*p)(int,int);p=max;mainmaxmin定義p為指向函數的指針變量,p指向一個帶整型返回值的函數.數據類型(*指針變量名)(參數列表)maxp例:求a和b中的大者。intmain(){intmax(int,int);inta,b,c,(*p)(int,int);
p=max;scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d",a,b,c);}注意:對函數指針變量p進行p++,p+n,p--等運算無意義.intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}當每次調用的函數不是固定的時,用指針變量就比較方便。#include<stdio.h>intmain(){inta,b,c,d,(*p)(int,int);a=3,b=5;p=max;c=(*p)(a,b);p=min;d=(*p)(a,b);printf("c=%d,d=%d\n",c,d);}intmax(intx,inty){ returnx>y?x:y;}intmin(intx,inty){ returnx<y?x:y;}intmain(){intmax(int,int),min(int,int),add(int,int);intprocess(intx,inty,int(*fun)(int,int));inta,b;scanf(“%d,%d”,&a,&b);printf(“max=”);process(a,b,max);printf(“min=”);process(a,b,min);printf(“sum=”);process(a,b,add);}例:設一個函數process,在調用它的時候,每次實現不同的功能。輸入a,b,分別求a,b中的大數,a,b中的小數和a,b之和。intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}intmin(intx,inty){intz;if(x<y)z=x;elsez=y;return(z);}intadd(intx,inty){intz;z=x+y;return(z);}intprocess(intx,inty,int(*fun)(int,int)){intresult;result=(*fun)(x,y);printf(“%d\n”,result);}例:設一個函數process,在調用它的時候,每次實現不同的功能。輸入a,b,分別求a,b中的大數,a,b中的小數和a,b之和。8.6返回指針值的函數一般定義形式為:
類型名*函數名(參數表)例如:int*a(intx,inty);8.6返回指針值的函數一般定義形式為:
類型名*函數名(參數表)例如:int*a(intx,inty);例:有若干個學生的成績(每個學生有4門課程),要求在用戶輸入學生序號以后,能輸出該學生的全部成績。intmain(){staticfloatscore[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};float*search(float(*pointer)[4],intn);float*p;inti,m;scanf("%d",&m);p=search(score,m);for(i=0;i<4;i++)printf("%5.2f\t",*(p+i));}float*search(float(*pointer)[4],intn){float*pt;pt=*(pointer+n);return(pt);}607080905689678834789066pointerpt【例】輸入一個字符串和一個字符,如果該字符在已知字符串中,從該字符第一次出現位置開始輸出字符串中剩余部分。要求定義如下函數找出該字符第一次出現的位置并返回主函數進行剩余字符串的輸出。char*match(char*s,charch){}#include<stdio.h>intmain(){ char*match(char*s,charch); charch,str[20],*p; p=NULL; printf(“請輸入字符串”); scanf(“%s”,str); getchar(); printf(“請輸入一個字符”); scanf(“%c”,&ch); if((p=match(str,ch))!=NULL) printf(“%s\n”,p); else printf(“字符不在已知字符串中\n”);}char*match(char*s,charch){ while(*s!=’\0’) {if(*s==ch) returns; else s++; }returnNULL;}8.7指針數組和指向指針的指針指針數組的概念
一個數組,其元素均為指針類型數據,稱為指針數組。定義形式為:類型名*數組名[數組長度]
例如:int*p[5];char*name[5];name[0]name[1]name[2]name[3]name[4]FollowmebasicgreatWallFORTRANComputerdesign利用指針數組求一維數組的最大值。#include<stdio.h>intmain(){ inta[5]={20,56,80,70,90},i,max; int*p[5];for(i=0;i<=4;i++) p[i]=&a[i]; max=*p[0]; for(i=1;i<=4;i++) if(*p[i]>max) max=*p[i]; printf(“max=%d\n”,max);}intmain(){staticchar*name[]={"followme","basic","greatwall","fortran","computerdesign"};intn=5;sort(name,n);print(name,n);}intsort(char*name[],intn){char*temp;inti,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;}}}intprint(char*name[],intn){inti;for(i=0;i<n;i++)printf(“%s\n”,name[i]);}指向指針的指針定義形式為:類型名**標識符例如:char**p;p=name+2;
name[0]name[1]name[2]name[3]name[4]FollowmebasicgreatWallFORTRANComputerdesignnamename+2pprintf("%o\n",*p);printf("%s\n",*p);結果為?例main(){staticchar*name[]={"Followme","BASIC","
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度聯營股本借款合同全文
- 2025鋁合金門窗制作合同
- 2025商務合作合同模板
- 2025全新版委托維修合同
- 2025年簽訂股權轉讓合同的要點分析及合同范本
- 2025年上海房屋租賃合同范本
- 2025年:探討合同規范化管理對企業發展的長遠意義
- 《危重患者的觀察要點》課件
- 《藝術史概述:唐宋元明清》課件
- 《供應鏈管理》課件
- 勞動保障協理員試題
- 安徽中等專業學校畢業生登記表
- 《多邊形的面積》單元整體作業設計
- 同濟大學《高等數學》第七版上、下冊答案(詳解)
- 三一sy215c8零件手冊SY215C8液壓挖掘機零部件圖冊
- 2023年和田地區體育教師招聘筆試題庫及答案
- GB/T 25150-2010工業設備化學清洗中奧氏體不銹鋼鈍化膜質量的測試方法藍點法
- 肉毒毒素作用機制理論測試
- GB/T 20641-2006低壓成套開關設備和控制設備空殼體的一般要求
- GB/T 18618-2002產品幾何量技術規范(GPS)表面結構輪廓法圖形參數
- GB/T 10183.1-2018起重機車輪及大車和小車軌道公差第1部分:總則
評論
0/150
提交評論