国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

C語(yǔ)言程序設(shè)計(jì)基礎(chǔ)講座之指針的慨念

2019-11-17 05:16:34
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  指針是C語(yǔ)言中廣泛使用的一種數(shù)據(jù)類型。 運(yùn)用指針編程是C語(yǔ)言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu); 能很方便地使用數(shù)組和字符串; 并能象匯編語(yǔ)言一樣處理內(nèi)存地址,從而編出精練而高效的程序。指針極大地豐富了C語(yǔ)言的功能。 學(xué)習(xí)指針是學(xué)習(xí)C語(yǔ)言中最重要的一環(huán), 能否正確理解和使用指針是我們是否把握C語(yǔ)言的一個(gè)標(biāo)志。同時(shí), 指針也是C語(yǔ)言中最為困難的一部分,在學(xué)習(xí)中除了要正確理解基本概念,還必須要多編程,上機(jī)調(diào)試。只要作到這些,指針也是不難把握的。

  指針的基本概念 在計(jì)算機(jī)中,所有的數(shù)據(jù)都是存放在存儲(chǔ)器中的。 一般把存儲(chǔ)器中的一個(gè)字節(jié)稱為一個(gè)內(nèi)存單元, 不同的數(shù)據(jù)類型所占用的內(nèi)存單元數(shù)不等,如整型量占2個(gè)單元,字符量占1個(gè)單元等, 在第二章中已有具體的介紹。為了正確地訪問(wèn)這些內(nèi)存單元, 必須為每個(gè)內(nèi)存單元編上號(hào)。 根據(jù)一個(gè)內(nèi)存單元的編號(hào)即可準(zhǔn)確地找到該內(nèi)存單元。內(nèi)存單元的編號(hào)也叫做地址。 既然根據(jù)內(nèi)存單元的編號(hào)或地址就可以找到所需的內(nèi)存單元,所以通常也把這個(gè)地址稱為指針。 內(nèi)存單元的指針和內(nèi)存單元的內(nèi)容是兩個(gè)不同的概念。 可以用一個(gè)通俗的例子來(lái)說(shuō)明它們之間的關(guān)系。我們到銀行去存取款時(shí), 銀行工作人員將根據(jù)我們的帳號(hào)去找我們的存款單, 找到之后在存單上寫入存款、取款的金額。在這里,帳號(hào)就是存單的指針, 存款數(shù)是存單的內(nèi)容。對(duì)于一個(gè)內(nèi)存單元來(lái)說(shuō),單元的地址即為指針, 其中存放的數(shù)據(jù)才是該單元的內(nèi)容。在C語(yǔ)言中, 答應(yīng)用一個(gè)變量來(lái)存放指針,這種變量稱為指針變量。因此, 一個(gè)指針變量的值就是某個(gè)內(nèi)存單元的地址或稱為某內(nèi)存單元的指針。圖中,設(shè)有字符變量C,其內(nèi)容為“K”(ASCII碼為十進(jìn)制數(shù) 75),C占用了011A號(hào)單元(地址用十六進(jìn)數(shù)表示)。設(shè)有指針變量P,內(nèi)容為011A, 這種情況我們稱為P指向變量C,或說(shuō)P是指向變量C的指針。 嚴(yán)格地說(shuō),一個(gè)指針是一個(gè)地址, 是一個(gè)常量。而一個(gè)指針變量卻可以被賦予不同的指針值,是變。 但在常把指針變量簡(jiǎn)稱為指針。為了避免混淆,我們中約定:“指針”是指地址, 是常量,“指針變量”是指取值為地址的變量。 定義指針的目的是為了通過(guò)指針去訪問(wèn)內(nèi)存單元。
 
  既然指針變量的值是一個(gè)地址, 那么這個(gè)地址不僅可以是變量的地址, 也可以是其它數(shù)據(jù)結(jié)構(gòu)的地址。在一個(gè)指針變量中存放一
個(gè)數(shù)組或一個(gè)函數(shù)的首地址有何意義呢? 因?yàn)閿?shù)組或函數(shù)都是連續(xù)存放的。通過(guò)訪問(wèn)指針變量取得了數(shù)組或函數(shù)的首地址, 也就找到了該數(shù)組或函數(shù)。這樣一來(lái), 凡是出現(xiàn)數(shù)組,函數(shù)的地方都可以用一個(gè)指針變量來(lái)表示, 只要該指針變量中賦予數(shù)組或函數(shù)的首地址即可。這樣做, 將會(huì)使程序的概念十分清楚,程序本身也精練,高效。在C語(yǔ)言中, 一種數(shù)據(jù)類型或數(shù)據(jù)結(jié)構(gòu)往往都占有一組連續(xù)的內(nèi)存單元。 用“地址”這個(gè)概念并不能很好地描述一種數(shù)據(jù)類型或數(shù)據(jù)結(jié)構(gòu), 而“指針”雖然實(shí)際上也是一個(gè)地址,但它卻是一個(gè)數(shù)據(jù)結(jié)構(gòu)的首地址, 它是“指向”一個(gè)數(shù)據(jù)結(jié)構(gòu)的,因而概念更為清楚,表示更為明確。 這也是引入“指針”概念的一個(gè)重要原因。 指針變量的類型說(shuō)明

  對(duì)指針變量的類型說(shuō)明包括三個(gè)內(nèi)容:

  (1)指針類型說(shuō)明,即定義變量為一個(gè)指針變量;

  (2)指針變量名;

  (3)變量值(指針)所指向的變量的數(shù)據(jù)類型。

  其一般形式為: 類型說(shuō)明符 *變量名;

  其中,*表示這是一個(gè)指針變量,變量名即為定義的指針變量名,類型說(shuō)明符表示本指針變量所指向的變量的數(shù)據(jù)類型。

  例如: int *p1;表示p1是一個(gè)指針變量,它的值是某個(gè)整型變量的地址。 或者說(shuō)p1指向一個(gè)整型變量。至于p1究竟指向哪一個(gè)整型變量, 應(yīng)由向p1賦予的地址來(lái)決定。

  再如:

staic int *p2; /*p2是指向靜態(tài)整型變量的指針變量*/
float *p3; /*p3是指向浮點(diǎn)變量的指針變量*/
char *p4; /*p4是指向字符變量的指針變量*/ 應(yīng)該注重的是,一個(gè)指針變量只能指向同類型的變量,如P3 只能指向浮點(diǎn)變量,不能時(shí)而指向一個(gè)浮點(diǎn)變量, 時(shí)而又指向一個(gè)字符變量。
  指針變量的賦值

  指針變量同普通變量一樣,使用之前不僅要定義說(shuō)明, 而且必須賦予具體的值。未經(jīng)賦值的指針變量不能使用, 否則將造成系統(tǒng)混亂,甚至死機(jī)。指針變量的賦值只能賦予地址, 決不能賦予任何其它數(shù)據(jù),否則將引起錯(cuò)誤。在C語(yǔ)言中, 變量的地址是由編譯系統(tǒng)分配的,對(duì)用戶完全透明,用戶不知道變量的具體地址。 C語(yǔ)言中提供了地址運(yùn)算符&來(lái)表示變量的地址。其一般形式為: & 變量名; 如&a變示變量a的地址,&b表示變量b的地址。 變量本身必須預(yù)先說(shuō)明。設(shè)有指向整型變量的指針變量p,如要把整型變量a 的地址賦予p可以有以下兩種方式:

  (1)指針變量初始化的方法

int a;
int *p=&a;
  (2)賦值語(yǔ)句的方法

int a;
int *p;
p=&a;
  不答應(yīng)把一個(gè)數(shù)賦予指針變量,故下面的賦值是錯(cuò)誤的: int *p;p=1000; 被賦值的指針變量前不能再加“*”說(shuō)明符,如寫為*p=&a 也是錯(cuò)誤的

  指針變量的運(yùn)算

  指針變量可以進(jìn)行某些運(yùn)算,但其運(yùn)算的種類是有限的。 它只能進(jìn)行賦值運(yùn)算和部分算術(shù)運(yùn)算及關(guān)系運(yùn)算。

  1.指針運(yùn)算符

  (1)取地址運(yùn)算符&

  取地址運(yùn)算符&是單目運(yùn)算符,其結(jié)合性為自右至左,其功能是取變量的地址。在scanf函數(shù)及前面介紹指針變量賦值中,我們已經(jīng)了解并使用了&運(yùn)算符。

  (2)取內(nèi)容運(yùn)算符*

  取內(nèi)容運(yùn)算符*是單目運(yùn)算符,其結(jié)合性為自右至左,用來(lái)表示指針變量所指的變量。在*運(yùn)算符之后跟的變量必須是指針變量。需要注重的是指針運(yùn)算符*和指針變量說(shuō)明中的指針說(shuō)明符* 不是一回事。在指針變量說(shuō)明中,“*”是類型說(shuō)明符,表示其后的變量是指針類型。而表達(dá)式中出現(xiàn)的“*”則是一個(gè)運(yùn)算符用以表示指針變量所指的變量。


main(){
 int a=5,*p=&a;
 PRintf ("%d",*p);
}
......
  表示指針變量p取得了整型變量a的地址。本語(yǔ)句表示輸出變量a的值。

  2.指針變量的運(yùn)算

  (1)賦值運(yùn)算

  指針變量的賦值運(yùn)算有以下幾種形式:

  ①指針變量初始化賦值,前面已作介紹。

  ②把一個(gè)變量的地址賦予指向相同數(shù)據(jù)類型的指針變量。例如:

int a,*pa;
pa=&a; /*把整型變量a的地址賦予整型指針變量pa*/
  ③把一個(gè)指針變量的值賦予指向相同類型變量的另一個(gè)指針變量。如:

int a,*pa=&a,*pb;
pb=pa; /*把a(bǔ)的地址賦予指針變量pb*/
  由于pa,pb均為指向整型變量的指針變量,因此可以相互賦值。

  ④把數(shù)組的首地址賦予指向數(shù)組的指針變量。

  例如:

int a[5],*pa;
pa=a; (數(shù)組名表示數(shù)組的首地址,故可賦予指向數(shù)組的指針變量pa)
  也可寫為:

pa=&a[0]; /*數(shù)組第一個(gè)元素的地址也是整個(gè)數(shù)組的首地址,
  也可賦予pa*/

  當(dāng)然也可采取初始化賦值的方法:

int a[5],*pa=a;
  ⑤把字符串的首地址賦予指向字符類型的指針變量。例如: char *pc;pc="c language";或用初始化賦值的方法寫為: char *pc="C Language"; 這里應(yīng)說(shuō)明的是并不是把整個(gè)字符串裝入指針變量, 而是把存放該字符串的字符數(shù)組的首地址裝入指針變量。 在后面還將具體介紹。

  ⑥把函數(shù)的入口地址賦予指向函數(shù)的指針變量。例如: int (*pf)();pf=f; /*f為函數(shù)名*/
  (2)加減算術(shù)運(yùn)算

  對(duì)于指向數(shù)組的指針變量,可以加上或減去一個(gè)整數(shù)n。設(shè)pa是指向數(shù)組a的指針變量,則pa+n,pa-n,pa++,++pa,pa--,--pa 運(yùn)算都是合法的。指針變量加或減一個(gè)整數(shù)n的意義是把指針指向的當(dāng)前位置(指向某數(shù)組元素)向前或向后移動(dòng)n個(gè)位置。應(yīng)該注重,數(shù)組指針變量向前或向后移動(dòng)一個(gè)位置和地址加1或減1 在概念上是不同的。因?yàn)閿?shù)組可以有不同的類型, 各種類型的數(shù)組元素所占的字節(jié)長(zhǎng)度是不同的。如指針變量加1,即向后移動(dòng)1 個(gè)位置表示指針變量指向下一個(gè)數(shù)據(jù)元素的首地址。而不是在原地址基礎(chǔ)上加1。

  例如:

int a[5],*pa;
pa=a; /*pa指向數(shù)組a,也是指向a[0]*/
pa=pa+2; /*pa指向a[2],即pa的值為&pa[2]*/ 指針變量的加減運(yùn)算只能對(duì)數(shù)組指針變量進(jìn)行, 對(duì)指向其它類型變量的指針變量作加減運(yùn)算是毫無(wú)意義的。(3)兩個(gè)指針變量之間的運(yùn)算只有指向同一數(shù)組的兩個(gè)指針變量之間才能進(jìn)行運(yùn)算, 否則運(yùn)算毫無(wú)意義。
  ①兩指針變量相減

  兩指針變量相減所得之差是兩個(gè)指針?biāo)笖?shù)組元素之間相差的元素個(gè)數(shù)。實(shí)際上是兩個(gè)指針值(地址) 相減之差再除以該數(shù)組元素的長(zhǎng)度(字節(jié)數(shù))。例如pf1和pf2 是指向同一浮點(diǎn)數(shù)組的兩個(gè)指針變量,設(shè)pf1的值為2010H,pf2的值為2000H,而浮點(diǎn)數(shù)組每個(gè)元素占4個(gè)字節(jié),所以pf1-pf2的結(jié)果為(2000H-2010H)/4=4,表示pf1和 pf2之間相差4個(gè)元素。兩個(gè)指針變量不能進(jìn)行加法運(yùn)算。 例如, pf1+pf2是什么意思呢?毫無(wú)實(shí)際意義。

  ②兩指針變量進(jìn)行關(guān)系運(yùn)算

  指向同一數(shù)組的兩指針變量進(jìn)行關(guān)系運(yùn)算可表示它們所指數(shù)組元素之間的關(guān)系。例如:

pf1==pf2表示pf1和pf2指向同一數(shù)組元素
pf1>pf2表示pf1處于高地址位置
pf1<pf2表示pf2處于低地址位置
main(){
 int a=10,b=20,s,t,*pa,*pb;
 pa=&a;
 pb=&b;
 s=*pa+*pb;
 t=*pa**pb;
 printf("a=%d/nb=%d/na+b=%d/na*b=%d/n",a,b,a+b,a*b);
 printf("s=%d/nt=%d/n",s,t);
}
......
  說(shuō)明pa,pb為整型指針變量

  給指針變量pa賦值,pa指向變量a。

  給指針變量pb賦值,pb指向變量b。

  本行的意義是求a+b之和,(*pa就是a,*pb就是b)。

  本行是求a*b之積。

  輸出結(jié)果。

  輸出結(jié)果。

  ......

  指針變量還可以與0比較。設(shè)p為指針變量,則p==0表明p是空指針,它不指向任何變量;p!=0表示p不是空指針。空指針是由對(duì)指針變量賦予0值而得到的。例如: #define NULL 0 int *p=NULL; 對(duì)指針變量賦0值和不賦值是不同的。指針變量未賦值時(shí),可以是任意值,是不能使用的。否則將造成意外錯(cuò)誤。而指針變量賦0值后,則可以使用,只是它不指向具體的變量而已。

main(){
 int a,b,c,*pmax,*pmin;
 printf("input three numbers:/n");
 scanf("%d%d%d",&a,&b,&c);
 if(a>b){
  pmax=&a;
  pmin=&b;
 }
 else{
  pmax=&b;
  pmin=&a;
 }
 if(c>*pmax) pmax=&c;
 if(c<*pmin) pmin=&c;
 printf("max=%d/nmin=%d/n",*pmax,*pmin);
}
......
  pmax,pmin為整型指針變量。

  輸入提示。

  輸入三個(gè)數(shù)字。

  假如第一個(gè)數(shù)字大于第二個(gè)數(shù)字...

  指針變量賦值

  指針變量賦值

  指針變量賦值

  指針變量賦值

  判定并賦值

  判定并賦值

  輸出結(jié)果

  ......
數(shù)組指針變量的說(shuō)明和使用

  指向數(shù)組的指針變量稱為數(shù)組指針變量。 在討論數(shù)組指針變量的說(shuō)明和使用之前,我們先明確幾個(gè)關(guān)系。

  一個(gè)數(shù)組是由連續(xù)的一塊內(nèi)存單元組成的。 數(shù)組名就是這塊連續(xù)內(nèi)存單元的首地址。一個(gè)數(shù)組也是由各個(gè)數(shù)組元素(下標(biāo)變量) 組成的。每個(gè)數(shù)組元素按其類型不同占有幾個(gè)連續(xù)的內(nèi)存單元。 一個(gè)數(shù)組元素的首地址也是指它所占有的幾個(gè)內(nèi)存單元的首地址。 一個(gè)指針變量既可以指向一個(gè)數(shù)組,也可以指向一個(gè)數(shù)組元素, 可把數(shù)組名或第一個(gè)元素的地址賦予它。如要使指針變量指向第i號(hào)元素可以把i元素的首地址賦予它或把數(shù)組名加i賦予它。

  設(shè)有實(shí)數(shù)組a,指向a的指針變量為pa,從圖6.3中我們可以看出有以下關(guān)系:

  pa,a,&a[0]均指向同一單元,它們是數(shù)組a的首地址,也是0 號(hào)元素a[0]的首地址。pa+1,a+1,&a[1]均指向1號(hào)元素a[1]。類推可知a+i,a+i,&a[i]

  指向i號(hào)元素a[i]。應(yīng)該說(shuō)明的是pa是變量,而a,&a[i]都是常量。在編程時(shí)應(yīng)予以注重。

main(){
 int a[5],i;
 for(i=0;i<5;i++){
  a[i]=i;
  printf("a[%d]=%d/n",i,a[i]);
 }
 printf("/n");
}
  主函數(shù)

  定義一個(gè)整型數(shù)組和一個(gè)整型變量

  循環(huán)語(yǔ)句

  給數(shù)組賦值

  打印每一個(gè)數(shù)組的值

  ......

  輸出換行

  ......

  數(shù)組指針變量說(shuō)明的一般形式為:

  類型說(shuō)明符 * 指針變量名

  其中類型說(shuō)明符表示所指數(shù)組的類型。 從一般形式可以看出指向數(shù)組的指針變量和指向普通變量的指針變量的說(shuō)明是相同的。
引入指針變量后,就可以用兩種方法來(lái)訪問(wèn)數(shù)組元素了。

  第一種方法為下標(biāo)法,即用a[i]形式訪問(wèn)數(shù)組元素。 在第四章中介紹數(shù)組時(shí)都是采用這種方法。

  第二種方法為指針?lè)ǎ床捎?(pa+i)形式,用間接訪問(wèn)的方法來(lái)訪問(wèn)數(shù)組元素。

main(){
 int a[5],i,*pa;
 pa=a;
 for(i=0;i<5;i++){
  *pa=i;
  pa++;
 }
 pa=a;
 for(i=0;i<5;i++){
  printf("a[%d]=%d/n",i,*pa);
  pa++;
 }
}
  主函數(shù)

  定義整型數(shù)組和指針

  將指針pa指向數(shù)組a

  循環(huán)

  將變量i的值賦給由指針pa指向的a[]的數(shù)組單元

  將指針pa指向a[]的下一個(gè)單元

  ......

  指針pa重新取得數(shù)組a的首地址

  循環(huán)

  用數(shù)組方式輸出數(shù)組a中的所有元素

  將指針pa指向a[]的下一個(gè)單元

  ......
  ......

  下面,另舉一例,該例與上例本意相同,但是實(shí)現(xiàn)方式不同。

main(){
 int a[5],i,*pa=a;
 for(i=0;i<5;){
  *pa=i;
  printf("a[%d]=%d/n",i++,*pa++);
 }
}
  主函數(shù)

  定義整型數(shù)組和指針,并使指針指向數(shù)組a

  循環(huán)

  將變量i的值賦給由指針pa指向的a[]的數(shù)組單元

  用指針輸出數(shù)組a中的所有元素,同時(shí)指針pa指向a[]的下一個(gè)單元

  ......
  ......
 
  數(shù)組名和數(shù)組指針變量作函數(shù)參數(shù)

  在第五章中曾經(jīng)介紹過(guò)用數(shù)組名作函數(shù)的實(shí)參和形參的問(wèn)題。在學(xué)習(xí)指針變量之后就更輕易理解這個(gè)問(wèn)題了。 數(shù)組名就是數(shù)組的首地址,實(shí)參向形參傳送數(shù)組名實(shí)際上就是傳送數(shù)組的地址, 形參得到該地址后也指向同一數(shù)組。 這就好象同一件物品有兩個(gè)彼此不同的名稱一樣。同樣,指針變量的值也是地址, 數(shù)組指針變量的值即為數(shù)組的首地址,當(dāng)然也可作為函數(shù)的參數(shù)使用。

float aver(float *pa);
main(){
 float sco[5],av,*sp;
 int i;
 sp=sco;
 printf("/ninput 5 scores:/n");
 for(i=0;i<5;i++) scanf("%f",&sco[i]);
 av=aver(sp);
 printf("average score is %5.2f",av);
}
float aver(float *pa)
{
 int i;
 float av,s=0;
 for(i=0;i<5;i++) s=s+*pa++;
 av=s/5;
 return av;
}

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 潞西市| 南部县| 正蓝旗| 平度市| 高邮市| 永德县| 怀安县| 拜泉县| 商丘市| 剑河县| 棋牌| 大名县| 瑞金市| 鹤峰县| 岳阳县| 虹口区| 明星| 宁蒗| 黎平县| 紫阳县| 昌邑市| 延庆县| 虎林市| 泸州市| 长治县| 砀山县| 松溪县| 双桥区| 宜川县| 常山县| 尚义县| 清涧县| 秭归县| 神农架林区| 松阳县| 绵竹市| 正阳县| 西盟| 互助| 庆云县| 兴安县|