




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、指針的概念指針的概念 指針類型是C語言中使用十分普遍的數(shù)據(jù)類型,它與一般的變量不同之處是它包含的不是數(shù)據(jù)的值,而是另一變量的地址。 指針是C語言中的一個重要概念,正確而熟練地掌握了指針的概念和指針的使用,就能設(shè)計出復雜的數(shù)據(jù)結(jié)構(gòu)和高效的程序,沒有掌握指針就沒有掌握C語言的精華。 凡是程序中定義的變量,在編譯時系統(tǒng)都給他們分配相應(yīng)的存貯單元,VC6.0系統(tǒng)給短整型分配2個字節(jié),給整形和實型分配4個字節(jié),每個變量所占的存貯單元都有確定的地址,具體地址在編譯時分配。指針的概念指針的概念 C程序的變量所存放的數(shù)據(jù): 數(shù)值型數(shù)據(jù):整數(shù)、實數(shù)通過前面的學習,我們已知道: 字符型數(shù)據(jù):字符、字符串 占有一定
2、長度的內(nèi)存 單元 如:int x; x占4字節(jié)、4個單元 每一個變量都有一個地址,為無符號整數(shù),它不同于一般的整數(shù)。問題:問題: 能否對地址運算? 能否用一個變量保存地址?這些變量具有的性質(zhì):這些變量具有的性質(zhì):例例: short int a=3, b=4; float c=4.5,d=8.6; char e=x,f=y;101010121014a101810221023bcdef344.58.6xy 要訪問內(nèi)存中的變量,在程序中是通過變量名來引用變量的值。但實際上,在編譯時將每個變量名對應(yīng)一個地址,在內(nèi)存中不再出現(xiàn)變量名而只有地址。 若程序中引用變量若程序中引用變量a,系統(tǒng)找到對應(yīng)地址,系統(tǒng)
3、找到對應(yīng)地址1010,然后從然后從1010,1011兩個字節(jié)中取出其中的值。兩個字節(jié)中取出其中的值。一、數(shù)據(jù)在內(nèi)存中的存放一、數(shù)據(jù)在內(nèi)存中的存放設(shè):系統(tǒng)分配i的起始地址為2000的單元內(nèi)存:為一個連續(xù)編號(連續(xù)地址)且以一個單元為一個字節(jié)的連續(xù)存貯區(qū)。 若程序中定義了三個int變量i, j, k short int i= 5, j=5, k=10; 則: j的起始地址有可能為為2002的單元k的起始地址有可能為2004的單元2000200120022003200420053001 5+5102000ijk當程序中要用它們的值時: y=i+j+k;找到j(luò)的地址2002,將2002,2003中的數(shù)
4、據(jù)5讀出;找到k的地址2004,將2004,2005中的數(shù)據(jù)10讀出。分別 找到i的地址2000,將2000,2001中的數(shù)據(jù)5讀出;則系統(tǒng)通過一張變量名與地址對應(yīng)關(guān)系表:上述過程稱為變量的 “直接訪問”然后把這些數(shù)據(jù)進行算術(shù)運算。直接訪問:直接使用存放該數(shù)據(jù)的變量名。i相當于使用 5使用變量如如:用pi, pj, pk來存放i, j, k的地址200020022004 55103001300330053007200020022004pipjpkijk 若要得到變量i的值,可以先訪問pi,得到i的地址,再通過該地址找到它i的值。顯然,pi與i是通過i的地址聯(lián)系起來的。 間接訪問:如果將某一變量
5、的地址(如i的地址2000)存放到另一個變量x,則可通過x來存取i的值。直接訪問直接訪問:通過變量名或地址訪問一個變量的方式通過變量名或地址訪問一個變量的方式為為“直接訪問直接訪問”。間接訪問:間接訪問:把地址存放在一個變量中,然后通過先找把地址存放在一個變量中,然后通過先找出地址變量中的值出地址變量中的值( (一個地址一個地址) ),再由此地址找,再由此地址找 到最終要到最終要訪問的變量的方法稱為訪問的變量的方法稱為“間接訪問間接訪問” 注:注: 存放地址的變量是一種特殊的變量,它只存放地址的變量是一種特殊的變量,它只能用來存放地址而不能用來存放其它類型的數(shù)據(jù)能用來存放地址而不能用來存放其它
6、類型的數(shù)據(jù),需要專門加以定義。,需要專門加以定義。8.2 8.2 指針和地址指針和地址指針變量定義指針變量定義:一個變量的地址稱為該變量的指針。因此,i的指針的值為2000。而存放地址(指針)的變量叫做指針變量。200020022004 55103001300330053007200020022004pipjpkijkPi就是指針變量指針變量的定義與初始化:指針變量的定義與初始化:表示該變量為指向某類型變量的指針變量。存儲類型 類型名 變量名注注1. 標識符前面的“*”標示該變量為指針變量。2. 一個指針變量只能指向同一類型的變量。指針變量指針變量的定義的定義int *p, i=3;P3i如:
7、 int p; (p為指向整型變量的指針) char *s;(s為指向字符型變量的指針) float *t;(t為指向浮點型變量的指針)p中只能存放整型變量的地址習慣用語:若指針變量p存放了變量a的地址,我們稱“p指向a”請區(qū)別:請區(qū)別: 指針:就是地址指針:就是地址 變量的指針:就是變量的地址變量的指針:就是變量的地址 指針變量:存放地址的變量指針變量:存放地址的變量重要概念:重要概念: 指針變量也有各種類型(如上面所示),但指針變量的值只能是整型值。指針變量的引用方式:指針變量的引用方式: *變量名-表示所指變量的值。 變量名-表示指向變量的指針(地址)。如 int *p; char *s
8、; float *t; *p=5; *s=a; *t=3.6; 但 p=p+1; 并不代表p=6,它代表的是地址1若有:float *t;且 *t=3.6; 設(shè)t的地址為2000,則t+12004例:例:若有:int *p 且 *p=5; 設(shè)p的地址為2000,則p+12004若有:char *s 且 *s=a; 設(shè)s的地址為2000,則s+12001三、引用指針變量三、引用指針變量將一個變量的地址(指針)賦給一個指針變量,用取地址運算符:& int i, j, p; i=3; p=&i;求出整型變量i的地址付給指針變量p例:例:&k &k 取變量取變量k k地
9、址地址 &c2 &c2 取數(shù)組元素取數(shù)組元素c2c2的地址的地址 &() &() 取結(jié)構(gòu)取結(jié)構(gòu)stst變量變量namename項的地址項的地址 &233, &(i+233) &233, &(i+233) & &:( (取地址運算符取地址運算符) )取當前變量的地址取當前變量的地址 運算對象不能是運算對象不能是常量表達式常量表達式或或寄存器變量寄存器變量 p=&i;3i&iP存取指針變量所指向變量(目標變量)的值:用指針運算符“ * ”, 即:*p 為 i。 , &
10、為同級運算符,結(jié)合性自右至左。當&或&在一起時,具有抵消作用。則:p=&i相當于p=i 如上例:int i, p ;i=3;p=&i;指針變量不要談”指”色變 指針是C語言學習中的一大難點。 難難在概念。main() int a,*p1,*p2=&a; a=100; p1=p2; *p1=*p2; 首先搞定*p 請看以下變量聲明語句 int a,*p1; char b,*p2; a,b 普通變量(存放某個數(shù)值或字符) p1,p2 指針變量(存放某個實體的地址)變量聲明時,如果變量名前帶 *號,表示該變量是個指針變量有關(guān)*p的小結(jié) 變量聲明時,*p表示定義
11、了一個用來存放變量地址而非數(shù)據(jù)(數(shù)值、字符等)的指針變量。 程序中引用時,*p表示取指針變量p所指變量的值。main() int a,*p1,*p2=&a; a=100; p1=p2; *p1=*p2; int *p; p=&a;小考一下,如何?以下程序的運行結(jié)果是什么?main() float x,y; int *p; x=3.14; p=&x; y=*p; printf(y=%fn,y);結(jié)果:y=-2621.000000 把int *p改為float *p后,結(jié)果正確:y=3.140000 指針變量能參加運算嗎? 指針變量和其他變量一樣,可以在各種表達式中參加運算
12、。 但指針變量和普通變量不同,只能進行以下三種運算:u賦值運算u算術(shù)運算 u指針比較C C語言中有關(guān)指針的運算符語言中有關(guān)指針的運算符 & & 運算符運算符: : 取地址運算符取地址運算符 * * 運算符運算符: : 指針運算符或指明運算符,指針運算符或指明運算符,* *p p代表代表p p所指變量所指變量注意:此處的注意:此處的* *p p與定義指針變量時用的與定義指針變量時用的* *p p的含義是不同的。的含義是不同的。 定義定義 int *p; 中的中的 * 不是運算符不是運算符, 它只是表示其后的變量是它只是表示其后的變量是 一指針變量一指針變量 程序中的程序中的 *p
13、,其中的,其中的*是一個指針運算符,是一個指針運算符,*p表示表示p指向的變指向的變量量如:如:printf(printf(“%d%d”, ,* *p);p); printf( printf(“%d%d”,a);,a);結(jié)果都為結(jié)果都為P3a&aP3a 3指針運算指針運算 指針變量初始化 變量聲明時賦值 main( ) int a=5,*p=&a; printf(“%d,%d,%dn”,p,*p,a) 指針變量一般賦值 程序處理時賦值結(jié)果:2000,5,5 1. 指針變量賦值運算例例 指針賦值運算。# include main()int a,b;a=100;b=200;int
14、*pa, *pb; /*定義int類型的指針變量*/pa=&a; /*將變量a的地址賦給指針變量 pa */pb=&b; /*將變量b的地址賦給指針變量pb */printf(*pa=%d, *pb=%dn, *pa, *pb);pa=pb; /*將指針pb賦給pa,兩者都指向變量b*/printf(*pa=%d, *pb=%dn, *pa, *pb);運行結(jié)果:*pa=100,*pb=200*pa=200,*pb=2002. 指針變量算術(shù)運算(1)指針變量與整數(shù)相加減 指針變量加上或減去一個整數(shù)n,相當于指針變量從當前的位置向后或向前移動m個內(nèi)存單元,其中m的值為:m = n
15、*指針數(shù)據(jù)類型的長度指針數(shù)據(jù)類型的長度 不同數(shù)據(jù)類型占據(jù)不同的長度,char類型占1個字節(jié),short int類型占2個字節(jié),int,float類型占4個字節(jié)。(2) 指針和整數(shù)可以進行加減例如:例如: p p是指向某數(shù)組的第一個元素的指針,則是指向某數(shù)組的第一個元素的指針,則p+np+n就就表示這數(shù)組第表示這數(shù)組第n+1n+1個元素的位置。個元素的位置。 一般說來:一般說來:p+np+n表示超過指針表示超過指針p p的當前位置的第的當前位置的第n n個對象的地址。在計算具體地址時,編譯程序根據(jù)個對象的地址。在計算具體地址時,編譯程序根據(jù)p p所指對象的長度所指對象的長度(sizeof)(si
16、zeof)將將n n放大。放大。(3) 空指針不能指向任何對象3. 指針變量的關(guān)系運算 p和q是兩個相同類型的指針變量,則它們之間存在p= =q, p!=q, pq, p=q等關(guān)系。 例如: int *p,i=2; p=&i; 假設(shè)i地址為3000,則p的值為3000, p=p+2;執(zhí)行后,p的內(nèi)容是多少呢?因為p是int類型的變量,所以占的長度為4個字節(jié),不難得出p的值為3000+243008。要注意,這里不是簡單的p加2就行了,所以p的值不是3002。 指針變量的初始化和指針所指的變量一般形式:存儲類型 數(shù)據(jù)類型 *指針名=初始地址值;賦給指針變量,不是賦給目標變量例 int i;
17、 int *p=&i;變量必須已說明過類型應(yīng)一致例 int *p=&i; int i;例 int i; int *p=&i; int *q=p;用已初始化指針變量作初值注: 指針變量的使用例 main( ) int i=10; int *p; *p=i; printf(“%d”,*p); 危險!例 main( ) int i=10,k; int *p; p=&k; *p=i; printf(“%d”,*p); 指針變量必須先賦值,再使用.2000200420062005整型變量i10指針變量p200120022003隨機空指針 空指針: int *p; p=NU
18、LL;NULL是什么?在stdio.h中,定義#define NULL 0所以 p=NULL;相當于 p=0;內(nèi)存使用常識:任何C程序的變量在內(nèi)存中的地址均由操作系統(tǒng)自動分配,不能由編程者通過賦值指定。p=NULL 表示p不指向任何變量。內(nèi)存的低端只供由操作系統(tǒng)使用(相當于政府機關(guān),普通百姓不能使用)。例例main( )main( ) int int * *p1,p1,* *p2,i1,i2;p2,i1,i2; scanf( scanf(“%d, %d%d, %d”,&i1,&i2);,&i1,&i2); p1=&i1; p2=&i2; p1=&
19、amp;i1; p2=&i2; printf( printf(“%d, %dn%d, %dn”, ,* *p1,p1,* *p2);p2); p2=p1; p2=p1; printf( printf(“%d, %dn%d, %dn”, ,* *p1,p1,* *p2);p2); &i1P13i1&i2P25i2運行情況運行情況: 3: 3,5 5&i1P13i1&i1P25i23,53,3main( )main( ) int int * *p1,p1,* *p2,p2,* *p,i1=3,i2=5;p,i1=3,i2=5; p1=&i1; p2=
20、&i2; p1=&i1; p2=&i2; p=p1; p1=p2; p2=p; p=p1; p1=p2; p2=p; printf( printf(“%d, %dn%d, %dn”, ,* *p1,p1,* *p2);p2); 例例運行情況運行情況: :5,3P13i1P25i2* *p1p1* *p2p2p1=&i1p1=&i1p2=&i2p2=&i2p=p1p=p1P P* *p p&i1p1=p2p1=p2&i2p2=p;p2=p;&i1&i1&i2main( )main( ) int int
21、 * *p1,p1,* *p2,i,i1,i2;p2,i,i1,i2; i1=3; i2=5; i1=3; i2=5; p1=&i1; p2=&i2; p1=&i1; p2=&i2; i= i=* *p1; p1; * *p1=p1=* *p2; p2; * *p2=i;p2=i; printf( printf(“i1=%d, i2=%dni1=%d, i2=%dn”,i1,i2);,i1,i2); 例 交換兩指針變量所指向的值運行情況運行情況: :i1=5, i2=3P13i1P25i2* *p1p1* *p2p2i i* *p p35&i1&
22、i2p1=&i1p1=&i1p2=&i2p2=&i2i=i=* *p1p1* *p1=p1=* *p2p2* *p2=i;p2=i;34、指針使用的幾個細節(jié)。設(shè)指針p指向變量a則: p+(或 p += 1),p指向下一個元素。 *p+,相當于*(p+)。因為,*和+同優(yōu)先級,+是右結(jié)合運算符。 *(p+)與*(+p)的作用不同。 *(p+):先取*p,再使p加1。 *(+p):先使p加1,再取*p。 (*p)+表示,p指向的元素值加1。8.2 指針與函數(shù)指針與函數(shù)指針和函數(shù)的關(guān)系主要有三個方面: 一是指針可以作為函數(shù)的參數(shù) 二是函數(shù)的返回值可以是指針 三是指針可
23、以指向函數(shù) 在前面介紹函數(shù)時,已經(jīng)介紹了C語言的函數(shù)的參數(shù)傳遞是以“傳值”方式進行變量參數(shù)的信息傳遞,被調(diào)函數(shù)不能直接改變主調(diào)函數(shù)中參數(shù)的值。 當引入指針的概念后,我們可以在主調(diào)函數(shù)中將要改變內(nèi)容的變量地址作為參數(shù)傳遞給被調(diào)函數(shù),而被調(diào)函數(shù)執(zhí)行時,就按這個地址去訪問變量參數(shù)的值,相應(yīng)的參數(shù)要被說明成指針類型。一、指針作為函數(shù)參數(shù)一、指針作為函數(shù)參數(shù)例如:例如:main( ) void sub(int *px, int *py ); int x, y; sub(&x,&y); printf(“%d,%dn”,x,y); void sub(int *px, int *py) *px
24、=10; *py=20;xypxpy101210141020運行結(jié)果:運行結(jié)果:10,20結(jié)論:用指針作函數(shù)的參數(shù),可以實現(xiàn)結(jié)論:用指針作函數(shù)的參數(shù),可以實現(xiàn)“通過被通過被調(diào)函數(shù)改變主調(diào)函數(shù)中變量的值調(diào)函數(shù)改變主調(diào)函數(shù)中變量的值”的目的。的目的。101210141. 指針作形參,實參為變量地址或指針例例 9.4 編寫一程序,通過函數(shù)輸出兩個數(shù)中的最大值。 #include void max(int *i, int *j) /*定義指針作形參的函數(shù)max */ if(*i*j) printf(max:%dn,*i); else printf(max:%dn,*j);main( ) int i=1
25、00, j=200; int *pi, *pj; pi=&i; pj=&j; max(&i,&j); /*用變量地址作為函數(shù)的實參*/ max(pi,pj); /*用指針作為函數(shù)的實參*/運行結(jié)果:max: 200max: 200(1) 數(shù)據(jù)復制方式 例例 9.5 通過函數(shù)交換數(shù)據(jù)程序a。2. 參數(shù)的傳遞方式 函數(shù)的參數(shù)傳遞方式有兩種,數(shù)據(jù)復制(亦稱為按值傳遞)和地址傳遞。main() int a=5, b=9; swap(a, b); printf(a=%d, b=%d, a, b);運行結(jié)果:a=5,b=9#include void swap(int x,i
26、nt y) int temp; temp=x; x=y; y=temp;參數(shù)的傳遞方向:參數(shù)的傳遞方向:單向值傳遞,而且是由調(diào)用者傳給子函數(shù). swap(int x, int y) int temp; temp=x; x=y; y=temp;main() int a=5,b=9; swap(a,b); printf(a=%d, b=%d, a, b);.20002008200A2002200420065變量a 變量b(main)9 變量temp 變量y 變量x(swap)559 59COPYswap(int x,int y) int temp; temp=x; x=y; y=temp;main
27、() int a=5,b=9; swap(a,b); printf(n%d,%dn,a,b);值傳遞.20002008200A2002200420065變量a 變量b(main)9運行結(jié)果:5, 9分析分析: 函數(shù)調(diào)用時,程序把a,b的值5,9傳遞給x,y,在swap( )函數(shù)中x,y交換之后,沒有把它們的結(jié)果返回給實參a,b,所以a,b并沒有交換,交換的只是x,y。a與x,b與y占用的是不同的內(nèi)存單元。 數(shù)據(jù)復制方式傳遞數(shù)據(jù)時,由于數(shù)據(jù)在傳遞方和被傳遞方占用不同的內(nèi)存空間,所以被調(diào)用函數(shù)中的變量不管怎么變化,都不會影響到調(diào)用函數(shù)中的實參的值。這就是上面程序中兩個數(shù)沒有交換的根本原因。(2)地
28、址傳遞方式main() int a=5,b=9; int *pa,*pb; pa=&a; pb=&b; swap(pa,pb); printf(n%d,%dn,a,b);運行結(jié)果:a=9,b=5#include void swap(int *p1, int *p2) int p; p = *p1; *p1 = *p2; *p2 = p;swap(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p;main() int a=5,b=9; int *pa,*pb; pa=&a; pb=&b; swap(pa,pb); pri
29、ntf(n%d,%dn,a,b);.20002008200A200220042006200C200E2010.59整型變量a 整型變量b(main)指針pa指針pb20002002(swap)指針p1指針p2整型p5920002002COPY5例 8.5 將數(shù)從大到小輸出swap(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p;main() int a=5,b=9; int *pa,*pb; pa=&a; pb=&b; swap(pa,pb); printf(n%d,%dn,a,b);.20002008200A20022004200620
溫馨提示
- 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)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 日用百貨買賣合同
- 2025年泰安普通貨運從業(yè)資格證模擬考試
- 公司內(nèi)部溝通平臺使用記錄表格(電子版)
- 商場多經(jīng)點位租賃合同
- 執(zhí)行和解協(xié)議書范例8篇
- 2025年高中化學新教材同步 必修第一冊 第1章 階段重點突破練(一)
- 小額放貸公司合同范本
- 按揭車轉(zhuǎn)讓合同范本
- 液晶聚合物LCP戰(zhàn)略市場規(guī)劃報告
- 大學計算機基礎(chǔ)(Windows10+Office2016)PPT完整全套教學課件
- 精素材:描寫植物的好詞好句好段
- 【高中語文】《登岳陽樓》課件17張+統(tǒng)編版高中語文必修下冊
- 華師大版八年級數(shù)學下冊全冊教案
- 四下語文學情分析-2
- 家園合作培養(yǎng)幼兒勞動行為習慣的行動研究
- 中國的能源安全 課件
- 鄭州市某路雨水污水改造工程施工組織設(shè)計
- 對口升學計算機組裝試卷答案
- 期末總結(jié)600字四篇
- DCDC中恒定導通時間控制模式COT介紹
評論
0/150
提交評論