




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
C語言程序設(shè)計(jì)任務(wù)式教程(微課版)
VisualC++1計(jì)算機(jī)工程學(xué)院模塊5指針及應(yīng)用任務(wù)1地址與指針任務(wù)2指針與數(shù)組任務(wù)3指針與函數(shù)
2計(jì)算機(jī)工程學(xué)院
任務(wù)1地址與指針
學(xué)習(xí)目標(biāo)了解指針與地址的概念、掌握指針變量的定義、初始化及指針的運(yùn)算。3計(jì)算機(jī)工程學(xué)院案例一指針與地址
1.問題描述程序在計(jì)算機(jī)中運(yùn)行的時(shí)候,所有數(shù)據(jù)都存放在內(nèi)存中。而內(nèi)存以字節(jié)為存儲(chǔ)單元存放數(shù)據(jù),不同的數(shù)據(jù)類型所占用的單元數(shù)不等。如整型占用4個(gè)單元,字符占用1個(gè)單元等。請編程驗(yàn)證計(jì)算機(jī)是如何存取需要的數(shù)據(jù)的。5.1.1案例講解4計(jì)算機(jī)工程學(xué)院2.編程分析為了正確訪問內(nèi)存單元,計(jì)算機(jī)系統(tǒng)為每個(gè)內(nèi)存單元進(jìn)行編號(hào),然后根據(jù)一個(gè)內(nèi)存單元的編號(hào)準(zhǔn)確地找到該內(nèi)存單元。內(nèi)存單元的編號(hào)也叫做地址。既然根據(jù)內(nèi)存單元的地址就可以找到所需的內(nèi)存單元,因此通常也把這個(gè)地址稱為指針。因此,要解決上面的問題,最好的辦法是定義一組連續(xù)存儲(chǔ)的變量,然后列出各變量的存儲(chǔ)地址和值,從而得到它們的存儲(chǔ)空間。5計(jì)算機(jī)工程學(xué)院程序描述如下:
void
main()
{
定義字符型變量charA
定義整型變量intB
定義長整型變量longC,longD
輸出charA的地址和值輸出intB的地址和值輸出longC、longD的地址和值
}6計(jì)算機(jī)工程學(xué)院3.編寫源程序
/*EX5_1.CPP*/#include<stdio.h>voidmain(){charcharA='A';intintB=1;longlongC=2,longD=4;printf("charA的地址:%X,",&charA);/*以十六進(jìn)制形式輸出charA的地址*/7計(jì)算機(jī)工程學(xué)院
printf("charA的值:%c\n",charA);
printf("intB的地址:%X,",&intB);printf("intB的值:%d\n",intB);printf("longC的地址:%X,",&longC);
printf("longC的值:%d\n",longC);
printf("longD的地址:%X,",&longD);printf("longD的值:%d\n",longD);}8計(jì)算機(jī)工程學(xué)院4.運(yùn)行結(jié)果如圖5-1所示。
圖5-1案例1運(yùn)行結(jié)果9計(jì)算機(jī)工程學(xué)院5.歸納分析
(1)系統(tǒng)根據(jù)變量的數(shù)據(jù)類型,分別為charA、intB、longC和longD分配1個(gè)、2(4)個(gè)、4個(gè)和4個(gè)字節(jié)的存儲(chǔ)單元,此時(shí)變量所占存儲(chǔ)單元的第一個(gè)字節(jié)的地址就是該變量的地址。在圖5-1中,變量charA的地址是12FF7C,intB的地址是12FF78,longC的地址是12FF74,longD的地址是12FF70。圖5-2給出了案例1一次運(yùn)行的內(nèi)存存儲(chǔ)示意。
10計(jì)算機(jī)工程學(xué)院圖5-2案例1內(nèi)存存儲(chǔ)示意圖11計(jì)算機(jī)工程學(xué)院由圖5-2可知12FF7C字節(jié)被定義為字符型變量charA。系統(tǒng)每次讀寫charA值的時(shí)候就是到12FF7C內(nèi)存中進(jìn)行讀寫操作。同樣,內(nèi)存12FF78至12FF79的兩個(gè)字節(jié)被定義為整型變量intB、內(nèi)存12FF74至12FF77的四個(gè)字節(jié)被定義為整型變量longC、內(nèi)存12FF70至12FF73的四個(gè)字節(jié)被定義為整型變量longD。程序?qū)ψ兞康淖x寫操作實(shí)際上就是對變量所在存儲(chǔ)空間進(jìn)行讀取或?qū)懭霐?shù)據(jù)。
(2)在C語言中通過“&”獲得數(shù)據(jù)的地址,“&”稱為取地址運(yùn)算符。因此,案例1中的語句12計(jì)算機(jī)工程學(xué)院
printf("charA的地址:%x,",&charA);的作用就是輸出變量charA的地址。
(3)通過變量名訪問數(shù)據(jù)時(shí),系統(tǒng)自動(dòng)完成變量名與存儲(chǔ)地址的轉(zhuǎn)換,這種訪問形式稱為“直接訪問”。此外,C語言中還有一種稱為“間接訪問”的形式。它首先將變量的存儲(chǔ)地址存入另一個(gè)變量中,這個(gè)存放地址的變量稱為指針變量,然后通過指針變量去訪問先前的變量。這時(shí),我們可以說指針變量指向那個(gè)變量。這種訪問形式類似于打電話時(shí)的呼叫轉(zhuǎn)移。13計(jì)算機(jī)工程學(xué)院案例二
指針變量
1.問題描述從鍵盤輸入a和b兩個(gè)整數(shù),按先大后小的順序輸出a和b。14計(jì)算機(jī)工程學(xué)院2.編程分析從鍵盤輸入a和b兩個(gè)整數(shù)后最好不要改變它們本身的值,因?yàn)槠渌绦蛑锌赡苓€會(huì)使用到這些原始數(shù)據(jù)。比較好的做法是根據(jù)我們的需要給原始數(shù)據(jù)做上“標(biāo)志”:將較大的數(shù)標(biāo)識(shí)為pMax,較小的數(shù)標(biāo)識(shí)為pMin。這樣在輸出時(shí)可以根據(jù)做好的標(biāo)志來輸出。這種形式類似于給別人取外號(hào)。程序描述如下:
15計(jì)算機(jī)工程學(xué)院
voidmain()
{
定義變量intA、intB
定義指針變量pIntMax、pIntMin、pIntTemp
從鍵盤輸入兩個(gè)整數(shù)給intA、intB
令pIntMax指向intA、pIntMin指向intB
如果pIntMax指向的值小于pIntMin指向的值,利用pIntTemp將pIntMax、pIntMin交換
輸出intA、intB的值
輸出pIntMax指向的值、pIntMin指向的值}
16計(jì)算機(jī)工程學(xué)院3.編寫源程序
/*EX5_2.CPP*/#include<stdio.h>voidmain(){ intintA,intB; int*pIntMax,*pIntMin,*pIntTemp; printf("請輸入兩個(gè)整數(shù)intA,intB:"); scanf("%d,%d",&intA,&intB); pIntMax=&intA;pIntMin=&intB;
17計(jì)算機(jī)工程學(xué)院 if(*pIntMax<*pIntMin) { pIntTemp=pIntMax; pIntMax=pIntMin; pIntMin=pIntTemp; }
printf("\nintA=%d,intB=%d\n",intA,intB); printf("max=%d,min=%d\n",*pIntMax,*pIntMin);}18計(jì)算機(jī)工程學(xué)院4.運(yùn)行結(jié)果如圖5-3所示。圖5-3案例2運(yùn)行結(jié)果19計(jì)算機(jī)工程學(xué)院5.歸納分析
(1)嚴(yán)格地說,指針是一個(gè)地址,是一個(gè)常量。而用來存放地址的指針變量卻可以被賦予不同的指針值,是變量。但有時(shí)也會(huì)把指針變量簡稱為指針。為了避免混淆,本書約定:“指針”是指地址,是常量,“指針變量”是指取值為地址的變量。定義指針變量的目的是為了通過指針變量去訪問它所指向的內(nèi)存單元。
20計(jì)算機(jī)工程學(xué)院
(2)定義指針變量包括三個(gè)內(nèi)容:類型說明符、指針標(biāo)識(shí)符和指針變量名。其中,類型說明符表示指針變量所指向數(shù)據(jù)的數(shù)據(jù)類型,指針標(biāo)識(shí)符用“*”表示。
其一般形式為:
類型說明符*變量名;例如,案例2中語句“int*pIntMax,*pIntMin,*pIntTemp;”就表示定義三個(gè)指針:pIntMax、pIntMin和pIntTemp,它們的類型都是int類型,也就是說它們可以指向其他int類型的變量。21計(jì)算機(jī)工程學(xué)院再如:
int*pInt1; /*pInt1是指向整型變量的指針變量*/float*pFloat2; /*pFloat2是指向浮點(diǎn)變量的指針變量*/char*pChar3; /*pChar3是指向字符變量的指針變量*/應(yīng)該注意的是,一個(gè)指針變量只能指向同類型的變量,如pFloat2
只能指向浮點(diǎn)變量,不能時(shí)而指向一個(gè)浮點(diǎn)型變量,時(shí)而又指向一個(gè)字符型變量。22計(jì)算機(jī)工程學(xué)院
(3)指針變量定義后要給它們賦值,使其指向某個(gè)變量。
賦值的方式有兩種:
一種是通過取地址符將變量的地址賦給指針變量,如語句“pIntMax=&intA;”就是將變量a的地址賦值給指針變量pMax;
另一種是把其他同類型的指針變量的值賦值過來,如語句“pIntTemp=pIntMax;”表示把pIntMax的值賦值給pIntTemp。此后,pIntMax、pIntTemp指向同一個(gè)存儲(chǔ)地址。23計(jì)算機(jī)工程學(xué)院
(4)當(dāng)一個(gè)指針變量指向某變量時(shí),指針變量的值和指針變量的內(nèi)容是兩個(gè)不同的含義。指針變量的值表示它所指向的變量的地址,而指針變量的內(nèi)容則表示所指向的變量的值。例如語句“pIntMax=&intA;”執(zhí)行后,pIntMax的值就是變量intA的存儲(chǔ)地址,pIntMax的內(nèi)容就是變量intA本身的值。C語言中通過“*”指針運(yùn)算符來獲得指針變量的內(nèi)容。因此,要獲得pIntMax的內(nèi)容可以使用*pIntMax來得到。案例2中的“*pIntMaxMax<*pIntMin”語句就是判斷pIntMax的內(nèi)容是否小于pIntMin的內(nèi)容。24計(jì)算機(jī)工程學(xué)院
同樣,程序最后的輸出語句“printf("max=%d,min=%d\n*pIntMax,*pIntMin);”表示輸出pIntMax和pIntMin的內(nèi)容(指向的變量)。案例2執(zhí)行時(shí)的內(nèi)存存儲(chǔ)示意圖如圖5-4所示。(a)程序初始化(b)輸入3,6后
25計(jì)算機(jī)工程學(xué)院(c)執(zhí)行完pIntMax=&Inta;(d)執(zhí)行完pIntTemp=pIntMax;pMin;plntMin=&IntB;語句后pIntMax=pIntMin;pMin語句后語句后圖5-4案例2執(zhí)行時(shí)內(nèi)存存儲(chǔ)示意圖26計(jì)算機(jī)工程學(xué)院
程序初始化時(shí),系統(tǒng)為變量及指針變量分配內(nèi)存空間:變量a、b的地址分別是FFD2和FFD4,指針變量pMax、pMin、pTemp的地址分別是FFD6、FFD8和FFDA,如圖5-4(a)。從鍵盤輸入數(shù)據(jù)(3,6)后賦值給變量a、b,如圖5-4(b)。執(zhí)行“pMax=&a;pMin=&b;”語句后,將變量a的地址(FFD2)賦值給指針變量pMax,將變量b的地址(FFD4)賦值給指針變量pMin,如圖5-4(c)。由于pMax指向的值(3)小于pMin指向的值(6),因此執(zhí)行語句“pTemp=pMax;pMax=pMin;
pMin=pTemp;”,將pMax、pMin的值互換,如圖5-4(d)。27計(jì)算機(jī)工程學(xué)院
(5)ANSI新標(biāo)準(zhǔn)增加了一種“void”指針類型,即可以定義一個(gè)指針變量,但不指定它是指向哪一種類型數(shù)據(jù)。(6)當(dāng)一個(gè)指針變量的值為0(或記為NULL)時(shí),表示所指向的是空指針。28計(jì)算機(jī)工程學(xué)院1.基本概念
變量的指針就是變量的地址。存放變量地址的變量是指針變量。即在C語言中,允許用一個(gè)變量來存放指針,這種變量稱為指針變量。因此,一個(gè)指針變量的值就是某個(gè)變量的地址或稱為某變量的指針。定義5.1:數(shù)據(jù)所占存儲(chǔ)單元的第一個(gè)字節(jié)的地址稱為指針。
5.1.2基礎(chǔ)理論
29計(jì)算機(jī)工程學(xué)院定義5.2:用來存放數(shù)據(jù)存儲(chǔ)首地址的變量稱為指針變量,指針變量的類型決定了每次存取的字節(jié)數(shù)定義5.3:指針變量的值就是它所指向的變量的地址。定義5.4:指針變量的內(nèi)容表示它所指向的變量。定義指針變量的一般形式為:
類型說明符*變量名;30計(jì)算機(jī)工程學(xué)院為了表示指針變量和它所指向的變量之間的關(guān)系,在程序中用“*”符號(hào)表示“指向”,例如,pMax代表指針變量,而*
pMax是pMax所指向的變量。由于指針變量存儲(chǔ)的是變量的地址,在進(jìn)行指針移動(dòng)和指針運(yùn)算(加、減)時(shí),一個(gè)指向整型的指針變量要移動(dòng)一個(gè)位置意味著要移動(dòng)4(2)個(gè)字節(jié),一個(gè)指向?qū)嵭偷闹羔樧兞恳苿?dòng)一個(gè)位置就要移動(dòng)4個(gè)字節(jié)。通過指針訪問它所指向的一個(gè)變量是以間接訪問的形式進(jìn)行的,所以比直接訪問一個(gè)變量要費(fèi)時(shí)間,而且不直觀。因?yàn)橥ㄟ^指針要訪問哪一個(gè)變量,取決于指針的值(即指向)。31計(jì)算機(jī)工程學(xué)院例如“*pMax<*pMin;”實(shí)際上就是“a<b;”,前者不僅速度慢而且目的不明。但由于指針變量是變量,我們可以通過改變它們的指向,動(dòng)態(tài)地以間接形式訪問不同的變量,這給程序員帶來靈活性,也使程序代碼編寫得更為簡潔和有效。我們要意識(shí)到:指針變量存放的是地址,因此所有使用地址標(biāo)識(shí)的對象都可以由指針變量來指向。例如:數(shù)組、結(jié)構(gòu)體、函數(shù)以及指針變量本身等等。32計(jì)算機(jī)工程學(xué)院
2.指針、指針變量的運(yùn)算
指針變量可以進(jìn)行某些運(yùn)算,但其運(yùn)算的種類是有限的。它只能進(jìn)行賦值運(yùn)算和部分算術(shù)運(yùn)算及關(guān)系運(yùn)算。
(1)指針運(yùn)算符①取地址運(yùn)算符&取地址運(yùn)算符&是單目運(yùn)算符,其結(jié)合性為自右至左,功能是取變量的地址。在scanf函數(shù)及前面介紹指針變量賦值中,我們已經(jīng)了解并使用了&運(yùn)算符。33計(jì)算機(jī)工程學(xué)院②取內(nèi)容運(yùn)算符*取內(nèi)容運(yùn)算符*是單目運(yùn)算符,其結(jié)合性為自右至左,用來表示指針變量所指的變量。在*運(yùn)算符之后跟的變量必須是指針變量。需要注意的是指針運(yùn)算符“*”和指針變量說明中的指針說明符“*”不是一回事。在指針變量說明中,“*”是類型說明符,表示其后的變量是指針類型。而表達(dá)式中出現(xiàn)的“*”則是一個(gè)運(yùn)算符用以表示指針變量所指向的變量。34計(jì)算機(jī)工程學(xué)院
(2)指針變量的賦值運(yùn)算①通過取地址符將變量的地址賦給指針變量。例如:
inta,*pA;
pA=&a;/*把整型變量a的地址賦予整型指針變量pA*/②把一個(gè)指針變量的值賦予同類型的另一個(gè)指針變量。例如:
inta,*pA=&a,*pB;35計(jì)算機(jī)工程學(xué)院
pB=pA;/*把a(bǔ)的地址賦予指針變量pB*/由于pA、pB均為指向整型變量的指針變量,因此可以相互賦值。③把數(shù)組的首地址賦予指向數(shù)組的指針變量。例如:
inta[5],*pA;pA=a;數(shù)組名表示數(shù)組的首地址,故可賦予指向數(shù)組的指針變量pA。由于數(shù)組第一個(gè)元素的地址也是整個(gè)數(shù)組的首地址,因此,也可寫為:
pA=&a[0];36計(jì)算機(jī)工程學(xué)院④把字符串的首地址賦予指向字符類型的指針變量。例如:
char*pc;pc="CLanguage";
這里應(yīng)說明的是并不是把整個(gè)字符串裝入指針變量,而是把存放該字符串的字符數(shù)組的首地址裝入指針變量。在后面還將詳細(xì)介紹。
⑤把函數(shù)的入口地址賦予指向函數(shù)的指針變量。例如:
int(*pf)();pf=f;/*f為函數(shù)名*/37計(jì)算機(jī)工程學(xué)院
(3)指針變量的加減算術(shù)運(yùn)算對于指向數(shù)組的指針變量,可以加上或減去一個(gè)整數(shù)n。設(shè)pA是指向數(shù)組a的指針變量(即pA指向a[0]),則pA+n表示把指針指向的當(dāng)前位置(指向某數(shù)組元素)向后移動(dòng)n個(gè)位置(即指向a[n])。指針變量的加減運(yùn)算只能對數(shù)組指針變量進(jìn)行,對指向其它類型變量的指針變量作加減運(yùn)算是毫無意義的。注意:①不能把一個(gè)數(shù)字直接賦值給指針變量。38計(jì)算機(jī)工程學(xué)院例如下面的語句是錯(cuò)誤的:
int*p=2000;
②程序中給指針變量賦值時(shí),前面不要加上“*”說明符。例如下面的語句是錯(cuò)誤的:
inta=1;int*p;*p=&a;
③取地址運(yùn)算符&和取內(nèi)容運(yùn)算符*是一對逆操作,同時(shí)出現(xiàn)時(shí)可以相互抵消。例如:&*p就等同于p。因?yàn)閜是指針變量,*p表示其指向的變量,&*p表示其指向的變量的地址,也就是p的值。39計(jì)算機(jī)工程學(xué)院
【實(shí)驗(yàn)5-1】閱讀下面的程序,然后思考問題。
/*EX5_3.CPP*/#include<stdio.h>voidmain(){inta,b;int*pointer_1,*pointer_2;a=100;b=10;pointer_1=&a;pointer_2=&b;
5.1.3技能訓(xùn)練
40計(jì)算機(jī)工程學(xué)院
printf("%d,%d\n",a,b);printf("%d,%d\n",*pointer_1,*pointer_2);}
問題1:程序中有兩處出現(xiàn)*pointer_1和*pointer_2,請區(qū)分它們的不同含義。
問題2:程序第5、6行的“pointer_1=&a;”和“pointer_2=&b;”能否寫成“*pointer_1=&a;”和“*pointer_2=&b;”?
問題3:如果已經(jīng)執(zhí)行了“pointer_1=&a;”語句,那么“&*pointer_1”的含義是什么?
問題4:*&a的含義是什么?41計(jì)算機(jī)工程學(xué)院
(1)編程分析
問題1:在“int*pointer_1,*pointer_2;”語句中,*表示指針標(biāo)識(shí)符,表示定義指針變量pointer_1和pointer_2。在“printf("%d,%d\n",*pointer_1,*pointer_2);”語句中,*是取內(nèi)容運(yùn)算符,*pointer_1表示獲得指針變量pointer_1的內(nèi)容,*pointer_2表示獲得指針變量pointer_2的內(nèi)容。
問題2:不能。因?yàn)?pointer_1表示指針變量pointer_1指向的變量,它的類型是int型,而&a表示變量a的地址,不能把地址賦值給int型變量42計(jì)算機(jī)工程學(xué)院
問題3:&*pointer_1可以寫為&(*pointer_1),即取指針變量pointer_1指向變量的地址,等同于pointer_1。
問題4:*&a可以寫為*(&a),&a表示取變量a的地址,*(&a)表示取該地址中變量的值,等同于a。43計(jì)算機(jī)工程學(xué)院
(2)在VC++集成環(huán)境中輸入上述程序,文件存成EX5_3.CPP,如圖5-5所示。圖5-5運(yùn)行結(jié)果44計(jì)算機(jī)工程學(xué)院【實(shí)驗(yàn)5-2】執(zhí)行以下程序,寫出運(yùn)行結(jié)果。
/*EX5_4.CPP*/#include<stdio.h>voidmain(){inta,b,k=4,m=6,*p1=&k,*p2=&m;a=p1==&m;
b=(*p1)/(*p2)+7;printf("a=%d\n",a);printf("b=%d\n",b);}
45計(jì)算機(jī)工程學(xué)院
(1)編程分析程序執(zhí)行完“inta,b,k=4,m=6,*p1=&k,*p2=&m;”語句后,為變量a、b、k、m,指針變量p1、p2分配內(nèi)存空間,并賦初值4、6給變量k、m,使p1指向k,p2指向m。如圖5-6。46計(jì)算機(jī)工程學(xué)院圖5-6內(nèi)存存儲(chǔ)示意圖47計(jì)算機(jī)工程學(xué)院語句“a=p1==&m;”可以寫為“a=(p1==&m);”,即取出變量m的地址與p1比較是否相等(也就是判斷p1是否指向變量m),將比較結(jié)果(0或1)賦值給變量a。由于p1指向的是變量k而不是變量m,因此a的值為0。語句“b=(*p1)/(*p2)+7;”表示將指針變量p1指向的變量除以p2指向的變量后與7求和,結(jié)果存入變量b。該語句等同于“b=k/m+7;”,因此B的值為7。48計(jì)算機(jī)工程學(xué)院
(2)在VC++集成環(huán)境中輸入上述程序,文件存成EX5_4.CPP,如圖5-7所示。圖5-7運(yùn)行結(jié)果49計(jì)算機(jī)工程學(xué)院
5.1.4拓展與練習(xí)
【練習(xí)1】以下程序中調(diào)用scanf函數(shù)給變量a輸入數(shù)值的方法是錯(cuò)誤的,其錯(cuò)誤原因是什么?如何改正?#include<stdio.h>voidmain(){int*p,q,a,b;p=&a;printf("inputa:");scanf("%d",*p);......}50計(jì)算機(jī)工程學(xué)院【練習(xí)2】已有定義int
k=2;int*p1,*p2;且p1和p2均已指向變量k,下面不能正確執(zhí)行的賦值語句是_________。A.k=*p1+*p2;B.p2=k;C.p1=p2;D.k=*p1*(*p2);51計(jì)算機(jī)工程學(xué)院【練習(xí)3】若有語句int*point,a=4;和point=&a;下面均代表地址的一組選項(xiàng)是________。A.a,point,*&aB.&*a,&a,*pointC.&point,*point,&aD.&a,&*point,point52計(jì)算機(jī)工程學(xué)院1.編程規(guī)范
(1)定義指針變量時(shí),*號(hào)既可以緊接類型,也可以在變量名之前。
例如:int*
pnsize;
或int*pnsize;
但不要寫做:int*pnSize;
建議采用第二種形式。
5.1.5編程規(guī)范與常見錯(cuò)誤
53計(jì)算機(jī)工程學(xué)院
(2)指針變量名必須具有一定的實(shí)際意義,形式為pxAbcFgh。p表示指針變量,x表示指針變量類型,Abc、Fgh表示連續(xù)有意義字符串。
如int*pnSize;p表示是指針變量,n表示該指針變量可以指向整型數(shù)據(jù),Size表示該指針變量的含義。(3)一般一次只聲明一個(gè)變量和指針變量,否則就會(huì)讓人混淆。
比如:int*a,b;看起來b好像也是個(gè)指針,其實(shí)不是。54計(jì)算機(jī)工程學(xué)院2.常見錯(cuò)誤
(1)使用未初始化的指針指針是C語言中的一個(gè)重要概念,也是比較難掌握的一個(gè)概念。C語言中指針是用于存放變量地址的。指針變量是C語言中的一個(gè)特殊類型的變量。指針變量定義后應(yīng)確定其指向。在沒有確定指針的具體指向前,指針變量的內(nèi)容是隨機(jī)的地址,盲目地引用將十分危險(xiǎn)。55計(jì)算機(jī)工程學(xué)院
(2)指針變量所指向的變量類型與其定義的類型不符定義指針變量的一般格式為:類型說明符*指針變量名;其中類型說明符規(guī)定的是指針變量所指向的變量的類型。C語言規(guī)定一個(gè)指針變量只能指向同一類型的變量。
(3)指針的錯(cuò)誤賦值指針變量的值是某個(gè)數(shù)據(jù)對象的地址,只允許取正的整數(shù)值。然而,千萬不能將它與整數(shù)類型變量相混淆。指針賦值,在賦值號(hào)右邊的應(yīng)是變量地址且是所指變量的地址。56計(jì)算機(jī)工程學(xué)院任務(wù)2指針與數(shù)組
學(xué)習(xí)目標(biāo)掌握指針訪問數(shù)組的方法,領(lǐng)會(huì)指針處理字符串的方法,了解指針數(shù)組、多級(jí)指針等概念。57計(jì)算機(jī)工程學(xué)院案例一通過指針變量訪問數(shù)組元素1.問題描述(星期數(shù)的判斷)已知2010年1月至12月的星期因子分別是4、0、0、3、5、1、3、6、2、4、0、2。通過2010年的日期與相應(yīng)星期因子計(jì)算后可以得到當(dāng)天是星期幾。計(jì)算方法如下:week=(monthSet+day)%7,其中week表示星期數(shù):0表示星期天、1表示星期一,……;monthSet表示該月的星期因子;day表示第幾天。
5.2.1案例講解58計(jì)算機(jī)工程學(xué)院例如,要知道2010年4月5日是星期幾,只要將4月的星期因子3加上日期5,再與7取模(week=(monthSet+day)%7=(3+5)%7=1),得1,表示該天是星期一。要求編寫C語言程序,從鍵盤輸入2010年的月份和日期,輸出星期幾。59計(jì)算機(jī)工程學(xué)院2.編程分析對于十二個(gè)月的星期因子,我們可以存放在一個(gè)一維數(shù)組中,然后根據(jù)用戶輸入的月份到數(shù)組中取出相應(yīng)的星期因子進(jìn)行計(jì)算。在C
語言中,指針和數(shù)組之間的關(guān)系非常密切。如果使用數(shù)組下標(biāo)形式訪問數(shù)組元素,每次都要進(jìn)行地址計(jì)算。例如,要訪問a[3],就要通過數(shù)組地址a加上3倍的數(shù)組元素大小得到a[3]地址才能訪問。因此,可以考慮使用指針變量的形式來提高數(shù)組訪問效率和程序靈活性。60計(jì)算機(jī)工程學(xué)院程序描述如下:
intmain(){
定義數(shù)組保存12個(gè)月的星期因子定義指針變量,并使指針變量指向數(shù)組從鍵盤輸入月份和日期,分別存入變量month和day
通過公式week=(monthSet+day)%7計(jì)算星期數(shù)
}61計(jì)算機(jī)工程學(xué)院3.編寫源程序
/*文件名:Ex5_5PP.C根據(jù)星期因子計(jì)算2010年某天的星期數(shù)程序暫不考慮用戶輸入日期的有效性*/#include<stdio.h>voidmain()
{intmonthSet[12]={4,0,0,3,5,1,3,6,2,4,0,2};intmonth=0,day=0,week=0;int*pMonthSet=monthSet;62計(jì)算機(jī)工程學(xué)院
printf("請輸入月份1-12:");scanf("%d",&month);printf("\n請輸入日期1-31:");scanf("%d",&day);printf("\n");
week=(*(pMonthSet+month-1)+day)%7;if(week==0)printf("星期天\n");
elseprintf("星期%d\n",week);}63計(jì)算機(jī)工程學(xué)院4.運(yùn)行結(jié)果如圖5-8所示。圖5-8案例1運(yùn)行結(jié)果64計(jì)算機(jī)工程學(xué)院5.歸納分析
(1)一個(gè)數(shù)組是由連續(xù)的一塊內(nèi)存單元組成的。一個(gè)數(shù)組包含若干元素,每個(gè)數(shù)組元素都在內(nèi)存中占用存儲(chǔ)單元,它們都有相應(yīng)的地址。所謂數(shù)組的指針是指數(shù)組的起始地址,數(shù)組元素的指針是數(shù)組元素的地址。數(shù)組名就是這塊連續(xù)內(nèi)存單元的首地址。案例1中,數(shù)組monthSet[12]擁有12個(gè)int類型的元素,它們在內(nèi)存中的存儲(chǔ)如圖5-9所示。圖中我們可以看出數(shù)組的地址就是數(shù)組第一個(gè)元素的地址,也是數(shù)組名monthSet所標(biāo)識(shí)的地址。數(shù)組中每個(gè)元素依次存放。65計(jì)算機(jī)工程學(xué)院圖5-9案例1數(shù)組存儲(chǔ)示意圖66計(jì)算機(jī)工程學(xué)院
(2)定義一個(gè)指向數(shù)組元素的指針變量的方法,與以前介紹的指針變量相同。例如:
intmonthSet[12];/*定義monthSet為包含12個(gè)整型數(shù)據(jù)的數(shù)組*/
int*pMonthSet;/*定義pMonthSet為指向整型變量的指針變量*/應(yīng)當(dāng)注意,因?yàn)閿?shù)組為int型,所以指針變量也應(yīng)為指向int型的指針變量。下面是對指針變量賦值:67計(jì)算機(jī)工程學(xué)院
pMonthSet=monthSet;
表示把數(shù)組monthSet的地址賦給指針變量pMonthSet。或者:
pMonthSet=&monthSet[0];表示把monthSet[0]元素的地址賦給指針變量pMonthSet。在執(zhí)行了“int*pMonthSet=monthSet;”語句后內(nèi)存結(jié)構(gòu)如圖5-10所示:68計(jì)算機(jī)工程學(xué)院圖5-10指針變量指向數(shù)組69指針表示下標(biāo)表示pIntMonthintMonthSetpIntMonth&intMonthSet[0]pIntMonth+n&intMonthSet[n]*pIntMonthintMonthSet[0]*(pIntMonth+n)intMonthSet[n]指針與下標(biāo)的對應(yīng)關(guān)系計(jì)算機(jī)工程學(xué)院案例二指向數(shù)組元素的指針變量
1.問題描述要求使用指針實(shí)現(xiàn)將鍵盤輸入的一維數(shù)組的元素打印出來。
71計(jì)算機(jī)工程學(xué)院2.編程分析定義數(shù)組后用一個(gè)指針變量指向數(shù)組首元素,然后通過循環(huán)接收鍵盤輸入,存放在指針變量表示的地址中,每次循環(huán)指針變量下移一格。待輸入完成后,再利用指針變量循環(huán)輸出數(shù)組元素。程序描述如下:voidmain(){
定義數(shù)組及計(jì)數(shù)器定義指針變量,并使指針變量指向數(shù)組72計(jì)算機(jī)工程學(xué)院通過記數(shù)器控制循環(huán):輸入數(shù)據(jù)到指針變量指向下一個(gè)數(shù)組元素恢復(fù)指針變量使其重新指向數(shù)組通過記數(shù)器控制循環(huán):輸出指針變量指向的元素指向下一個(gè)數(shù)組元素}73計(jì)算機(jī)工程學(xué)院3.編寫源程序
/*文件名:Ex5_6.CPP*/#include<stdio.h>voidmain()
{inta[10],i;int*p=a;printf("請輸入十個(gè)整數(shù):\n");for(i=0;i<10;i++)scanf("%d",p++);printf("輸出:\n");
74計(jì)算機(jī)工程學(xué)院p=a;for(i=0;i<10;i++)
printf("%2d",*p++);printf("\n");
}4.運(yùn)行結(jié)果如圖5-11所示。圖5-11案例2運(yùn)行結(jié)果75計(jì)算機(jī)工程學(xué)院5.歸納分析
(1)由于p是指針變量,本身就表示地址,因此在使用scanf輸入時(shí)可以直接使用。例如:“scanf("%d",p);”。案例2中采用了“scanf("%d",p++);”語句,表示將輸入的數(shù)據(jù)存入p表示的地址中,然后將p指向下一個(gè)數(shù)組元素。在這里,“scanf("%d",p++);”語句也可以使用“scanf("%d",&a[i++]);”代替。76計(jì)算機(jī)工程學(xué)院
(2)使用指針變量時(shí)要注意它的當(dāng)前值。例如,通過“scanf("%d",p++);”語句循環(huán)為數(shù)組賦值后,p已經(jīng)超出了數(shù)組的存儲(chǔ)范圍,因此再次使用p輸出數(shù)組元素時(shí)需要再次執(zhí)行“p=a;”,使其重新指向數(shù)組首地址。77計(jì)算機(jī)工程學(xué)院案例三使用指針變量訪問二維數(shù)組
1.問題描述如果已知2010年至2015年的星期因子,同樣可以利用公式week=(monthSet+day)%7求解。請編程實(shí)現(xiàn)。78計(jì)算機(jī)工程學(xué)院表5-22010年至2015年的星期因子79計(jì)算機(jī)工程學(xué)院2.編程分析在案例1中,對于2010年一年的星期因子,我們使用了一維數(shù)組來存儲(chǔ)。在本例中我們可以使用二維數(shù)組來表示數(shù)據(jù):每年的星期因子占一行,每行12列,共6行。這樣,我們可以在程序中定義一個(gè)6行12列的數(shù)組monthSets[6][12],對其初始化后,由用戶輸入年份數(shù)據(jù)轉(zhuǎn)入相應(yīng)行查找對應(yīng)的星期因子,進(jìn)行計(jì)算。程序描述如下:80計(jì)算機(jī)工程學(xué)院voidmain(){
定義數(shù)組monthSets[6][12]保存每年的星期因子定義指針變量pMonthSets
從鍵盤輸入年份、月份和日期,分別存入變量year、month和day
根據(jù)year移動(dòng)指針通過公式week=(monthSet+day)%7計(jì)算星期數(shù)
}81計(jì)算機(jī)工程學(xué)院3.編寫源程序
/*文件名:Ex5_7.CPP根據(jù)星期因子計(jì)算2010-2015年某天的星期數(shù)程序暫不考慮用戶輸入日期的有效性*/#include<stdio.h>voidmain(){
int
monthSets[6][12]={{4,0,0,3,5,1,3,6,2,4,0,2},{5,1,1,4,6,2,4,0,3,5,1,3},
{6,2,3,6,1,4,6,2,5,0,3,5},82計(jì)算機(jī)工程學(xué)院{1,4,4,0,2,5,0,3,6,1,4,6},{2,5,5,1,3,6,1,4,0,2,5,0},{3,6,6,2,4,0,2,5,1,3,6,1}};/*2010----2015年星期因子*/intyear=0,month=0,day=0,week=0;
int
*pMonthSets=monthSets[0];printf("請輸入年份2010-2015:");scanf("%d",&year);printf("請輸入月份1-12:");scanf("%d",&month);83計(jì)算機(jī)工程學(xué)院printf("\n請輸入日期1-31:");scanf("%d",&day);printf("\n");
pMonthSets=*(monthSets+year-2010);
week=(*(pMonthSets+month-1)+day)%7;if(week==0)printf("星期天\n");elseprintf("星期%d\n",week);}84計(jì)算機(jī)工程學(xué)院4.運(yùn)行結(jié)果如圖5-12所示。圖5-12案例3運(yùn)行結(jié)果85計(jì)算機(jī)工程學(xué)院5.歸納分析
(1)C語言把一個(gè)二維數(shù)組看作是一維數(shù)組的集合,即二維數(shù)組是一個(gè)特殊的一維數(shù)組——它的元素也是一個(gè)一維數(shù)組。因此數(shù)組monthSets可分解為六個(gè)一維數(shù)組,即monthSets[0],monthSets[1],……,monthSets[5]。每一個(gè)一維數(shù)組又含有12個(gè)元素:monthSets[0][0]……monthSets[0][11],monthSets
[1][0]……monthSets[1][11]等。因此,程序中“int*pMonthSets=monthSets[0];”語句表示指針變量pMonthSets指向數(shù)組的第0行。86計(jì)算機(jī)工程學(xué)院
(2)圖5-13是該程序運(yùn)行時(shí)數(shù)組monthSets的存儲(chǔ)示意圖,從圖中我們可以看出:數(shù)組的名字表示數(shù)組monthSets的首地址,如果對其加1,則表示它的下一個(gè)元素地址,也就是monthSets[1],即二維數(shù)組的第1行。程序中“pMonthSets=monthSets
+year-2010;”語句將用戶輸入的年份減去2010得到偏移量,然后將數(shù)組首地址monthSets加上偏移量,使指針變量pMonthSets指向相應(yīng)的行數(shù)組。例如,用戶輸入2012作為年份,2012減去2010得2,pMonthSets加上2表示第2行,因此pMonthSets
=monthSets
[2]。87計(jì)算機(jī)工程學(xué)院圖5-13案例3數(shù)組monthSets的存儲(chǔ)示意圖
(3)對于二維數(shù)組monthSets的某一行,monthSets[i]就是它所表示的一維數(shù)組的數(shù)組名,也就是這行一維數(shù)組的首地址(如圖5-13)。如果對其加1,則表示這個(gè)一維數(shù)組的下一個(gè)元素88計(jì)算機(jī)工程學(xué)院地址,也就是monthSets[i][1]。語句“week=(*(pMonthSets
+
month
-1)+day)%7;”
將用戶輸入的月份減去1得到星期因子的偏移量,然后與pMonthSets相加,得到相應(yīng)元素的地址,通過“*”取出該地址的數(shù)據(jù)后進(jìn)行計(jì)算。例如用戶輸入2012作為年份,2作為月份時(shí),由前面的描述可知pMonthSets
=monthSets[2],pMonthSets+2-1得到monthSets[2][1]元素的地址。因此*(pMonthSets+2-1)得到的就是數(shù)組monthSets[2][1]元素的值:2。89計(jì)算機(jī)工程學(xué)院案例四指向多維數(shù)組的指針變量
1.問題描述在C語言里,有一種指針變量是專門用來指向多維數(shù)組的,稱為“指向多維數(shù)組的指針變量”。請使用這種指針變量來實(shí)現(xiàn)案例3。90計(jì)算機(jī)工程學(xué)院2.編程分析我們可以通過:“類型說明符(*指針變量名)[指向的一維數(shù)組的個(gè)數(shù)]”的形式來定義一個(gè)指向二維數(shù)組的指針變量。這樣,在對指針變量進(jìn)行加減操作時(shí),指針將在二維數(shù)組的行上移動(dòng)。程序描述如下:
91計(jì)算機(jī)工程學(xué)院
void
main(){定義數(shù)組monthSets[6][12]保存每年的星期因子定義指向二維數(shù)組的指針變量pMonthSets
從鍵盤輸入年份、月份和日期,分別存入變量year、month和day根據(jù)year移動(dòng)pMonthSets
通過公式week=(monthSet+day)%7計(jì)算星期數(shù)}92計(jì)算機(jī)工程學(xué)院3.編寫源程序
/*文件名:Ex5_8.CPP通過指向二維數(shù)組的指針變量實(shí)現(xiàn):根據(jù)星期因子計(jì)算2010-2015年某天的星期數(shù)程序暫不考慮用戶輸入日期的有效性*/#include<stdio.h>voidmain(){intmonthSets[6][12]={{4,0,0,3,5,1,3,6,2,4,0,2},93計(jì)算機(jī)工程學(xué)院
{5,1,1,4,6,2,4,0,3,5,1,3},{6,2,3,6,1,4,6,2,5,0,3,5},{1,4,4,0,2,5,0,3,6,1,4,6},{2,5,5,1,3,6,1,4,0,2,5,0},{3,6,6,2,4,0,2,5,1,3,6,1}};/*2010----2015年星期因子*/intyear=0,month=0,day=1,week=0;int(*pMonthSets)[12];/*定義指向二維數(shù)組的指針變量*/
pMonthSets=monthSets;printf("請輸入年份2010-2015:");scanf("%d",&year);94計(jì)算機(jī)工程學(xué)院
printf("請輸入月份1-12:");scanf("%d",&month);printf("\n請輸入日期1-31:");scanf("%d",&day);printf("\n");
pMonthSets+=year-2010;week=(*(*pMonthSets+month-1)+day)%7;if(week==0)printf("星期天\n");elseprintf("星期%d\n",week);}95計(jì)算機(jī)工程學(xué)院4.運(yùn)行結(jié)果如圖5-14所示。圖5-14案例4運(yùn)行結(jié)果96計(jì)算機(jī)工程學(xué)院5.歸納分析
(1)指向二維數(shù)組的指針變量定義方法為:類型說明符(*指針變量名)[指向的一維數(shù)組的個(gè)數(shù)];程序中通過“int(*pMonthSets)[12];”語句定義了一個(gè)可以指向二維數(shù)組的指針變量pMonthSets,這個(gè)二維數(shù)組每行擁有12列數(shù)據(jù)。97計(jì)算機(jī)工程學(xué)院
(2)語句“pMonthSets=monthSets;”使指針變量pMonthSets指向二維數(shù)組monthSets的首行。以后對pMonthSets加1就是下移一行,減1就是上移一行。(3)如果要訪問指針變量所指向的一維數(shù)組的內(nèi)容時(shí),要先用“*指針變量名”得到該行的首地址,然后加減偏移量得到元素所在地址,最后再通過“*”取出內(nèi)容。因此語句一般類似于:“*(*指針變量名±偏移量)”。例如,程序中的“*(*pMonthSets+month-1)”。98計(jì)算機(jī)工程學(xué)院案例五指針數(shù)組
1.問題描述指針變量也是一種數(shù)據(jù)類型。因此可以將一組同一類型的指針變量放在一起,定義為數(shù)組。這種由指針變量構(gòu)成的數(shù)組稱為指針數(shù)組。請使用指針數(shù)組實(shí)現(xiàn)案例3。99計(jì)算機(jī)工程學(xué)院2.編程分析前面的描述中,我們知道二維數(shù)組是由一組一維數(shù)組組成的,每個(gè)一維數(shù)組都有其首地址,也就是二維數(shù)組每行的行地址。因此,我們可以定義一個(gè)指針數(shù)組來分別指向二維數(shù)組中的行地址,實(shí)現(xiàn)對數(shù)組元素的訪問。程序描述如下:
void
main(){
定義數(shù)組monthSets[6][12]保存每年的星期因子100計(jì)算機(jī)工程學(xué)院定義指針數(shù)組的變量monthSetsRow將monthSets每行的行地址賦值給指針數(shù)組monthSetsRow的元素從鍵盤輸入年份、月份和日期,分別存入變量year、month和day
根據(jù)year獲得monthSetsRow中對應(yīng)行的地址通過公式week=(monthSet+day)%7計(jì)算星期數(shù)
}101計(jì)算機(jī)工程學(xué)院3.編寫源程序
/*文件名:Ex5_9.CPP通過指針數(shù)組實(shí)現(xiàn):根據(jù)星期因子計(jì)算2010-2015年某天的星期數(shù)程序暫不考慮用戶輸入日期的有效性*/#include<stdio.h>voidmain(){intmonthSets[6][12]={{4,0,0,3,5,1,3,6,2,4,0,2},102計(jì)算機(jī)工程學(xué)院
{5,1,1,4,6,2,4,0,3,5,1,3},{6,2,3,6,1,4,6,2,5,0,3,5},{1,4,4,0,2,5,0,3,6,1,4,6},{2,5,5,1,3,6,1,4,0,2,5,0},{3,6,6,2,4,0,2,5,1,3,6,1}};/*2010----2015年星期因子*/intyear=2012,month=2,day=1,week=0,i;int*monthSetsRow[6];for(i=0;i<6;i++)monthSetsRow[i]=monthSets[i];printf("請輸入年份2010-2015:");scanf("%d",&year);103計(jì)算機(jī)工程學(xué)院printf("請輸入月份1-12:");scanf("%d",&month);printf("\n請輸入日期1-31:");scanf("%d",&day);printf("\n");
week=(*(monthSetsRow[year-2010]+month-1)+day)%7;if(week==0)printf("星期天\n");elseprintf("星期%d\n",week);}104計(jì)算機(jī)工程學(xué)院4.運(yùn)行結(jié)果如圖5-15所示。圖5-15案例5運(yùn)行結(jié)果105計(jì)算機(jī)工程學(xué)院5.歸納分析
(1)指針數(shù)組是一組有序的指針的集合。指針數(shù)組的所有元素都必須是具有相同存儲(chǔ)類型和指向相同數(shù)據(jù)類型的指針變量。定義指針數(shù)組的一般形式為:
類型說明符*數(shù)組名[數(shù)組長度];其中類型說明符為指針值所指向的變量的類型。例如:int*monthSetsRow[6];表示monthSetsRow是一個(gè)指針數(shù)組,它有6個(gè)數(shù)組元素,每個(gè)元素值都是一個(gè)指針,指向整型變量。106計(jì)算機(jī)工程學(xué)院
(2)應(yīng)該注意指針數(shù)組和二維數(shù)組指針變量的區(qū)別。這兩者雖然都可用來表示二維數(shù)組,但是其表示方法和意義是不同的。二維數(shù)組指針變量是單個(gè)的變量,其一般形式中“(*指針變量名)”兩邊的括號(hào)不可少。而指針數(shù)組類型表示的是多個(gè)指針(一組有序指針)在一般形式中“*指針數(shù)組名”兩邊不能有括號(hào)。例如:int
(*p)[3];表示一個(gè)指向二維數(shù)組的指針變量。該二維數(shù)組的列數(shù)為3,或者說分解為一維數(shù)組的長度為3。int
*p[3];表示p是一個(gè)指針數(shù)組,有三個(gè)下標(biāo)變量p[0],p[1],p[2]均為指針變量。107計(jì)算機(jī)工程學(xué)院案例六使用指針變量處理字符串
1.問題描述用戶在輸入用戶名和密碼時(shí),如果輸入一些特殊符號(hào)可能會(huì)影響系統(tǒng)安全。因此需要將用戶輸入的用戶名和密碼進(jìn)行字符替換,將危險(xiǎn)字符替換掉。請編寫程序?qū)崿F(xiàn)將字符串中的“’”全部替換為字母“A”。108計(jì)算機(jī)工程學(xué)院2.編程分析
C語言中字符串是通過一維字符數(shù)組來存儲(chǔ)的,它的結(jié)束符為’\0’。因此我們可以使用指針變量指向字符串(一維字符數(shù)組),循環(huán)檢測每個(gè)字符直到結(jié)束(等于’\0’)為止。程序描述如下:
109計(jì)算機(jī)工程學(xué)院
void
main(){用戶輸入字符串存入字符數(shù)組str
定義指向字符的指針變量pStr,并使pStr指向數(shù)組str
如果pStr的內(nèi)容不等于’\0’做循環(huán):如果pStr的內(nèi)容等于’\’’,替換為’A’
pStr下移一個(gè)元素輸出替換后的字符串
}110計(jì)算機(jī)工程學(xué)院3.編寫源程序/*文件名:Ex5_10.CPP將字符串中的’全部替換為字母A。*/#include<stdio.h>voidmain()
{charstr[20];char*pStr=str;puts("請輸入字符串:");gets(str);111計(jì)算機(jī)工程學(xué)院
while(*pStr!='\0'){if(*pStr=='\'')*pStr='A';pStr++;}puts(str);}112計(jì)算機(jī)工程學(xué)院4.運(yùn)行結(jié)果如圖5-16所示。圖5-16案例6運(yùn)行結(jié)果113計(jì)算機(jī)工程學(xué)院5.歸納分析
(1)C語言中字符串是通過一維字符數(shù)組來存儲(chǔ)的,它的結(jié)束符為’\0’。因此對字符串中字符的引用也可以用指針來表示。(2)如果定義字符串時(shí)采用char
*str=”hello”;語句時(shí),雖然沒用顯式地定義字符數(shù)組,但實(shí)際上還是在內(nèi)存中開辟了一個(gè)連續(xù)區(qū)域存放字符串。114計(jì)算機(jī)工程學(xué)院
(3)雖然字符串是通過一維字符數(shù)組來存儲(chǔ)的,但是定義時(shí)不能寫為:
charst[20];st={"CLanguage"};而只能對字符數(shù)組的各元素逐個(gè)賦值。這也可看出使用指針變量更加方便。115計(jì)算機(jī)工程學(xué)院案例七main函數(shù)的參數(shù)
1.問題描述
C語言規(guī)定main函數(shù)的參數(shù)只能有兩個(gè),習(xí)慣上這兩個(gè)參數(shù)寫為argc和argv。請使用main函數(shù)參數(shù)實(shí)現(xiàn)案例6的功能。116計(jì)算機(jī)工程學(xué)院2.編程分析C語言規(guī)定argc必須是整型變量,argv必須是指向字符串的指針數(shù)組。加上形參說明后,main函數(shù)的函數(shù)頭應(yīng)寫為:
main(intargc,char*argv[])
main函數(shù)的參數(shù)值是從操作系統(tǒng)命令行上獲得的。當(dāng)我們要運(yùn)行一個(gè)可執(zhí)行文件時(shí),在DOS提示符下鍵入文件名,再輸入實(shí)際參數(shù)即可把這些實(shí)參傳送到main的形參中去。117計(jì)算機(jī)工程學(xué)院
DOS提示符下命令行的一般形式為:
C:\>可執(zhí)行文件名參數(shù)1
參數(shù)2……命令執(zhí)行時(shí),會(huì)將可執(zhí)行文件名、參數(shù)1、參數(shù)2等作為字符串,并將其地址按次序傳遞給argv指針數(shù)組,將字符串的個(gè)數(shù)傳遞給argc。因此,程序可以描述為:
main(){
定義指向字符的指針變量pStr118計(jì)算機(jī)工程學(xué)院檢測命令行參數(shù)是否存在使pStr指向命令行參數(shù)如果pStr的內(nèi)容不等于’\0’做循環(huán):如果pStr的內(nèi)容等于’\’
’,替換為’A’
pStr下移一個(gè)元素輸出替換后的字符串
}119計(jì)算機(jī)工程學(xué)院3.編寫源程序
/*文件名:Ex5_11.CPP使用main參數(shù)實(shí)現(xiàn):將字符串中的'全部替換為字母A。*/#include<stdio.h>voidmain(intargc,char*argv[]){char*pStr;if(argc!=2)printf("使用方法:輸入程序名字符串\n");120計(jì)算機(jī)工程學(xué)院
{pStr=argv[1];while(*pStr!='\0'){if(*pStr=='\'')*pStr='A';
pStr++;}printf("%s\n",argv[1]);
}}121計(jì)算機(jī)工程學(xué)院4.程序運(yùn)行方法①在VC環(huán)境中右鍵單擊項(xiàng)目名,選擇“settings”圖5-17案例7步驟一122計(jì)算機(jī)工程學(xué)院②在彈出的窗口中選擇“Debug”,在“programarguments”中輸入命令行參數(shù),例如“asd’fgh’123”,點(diǎn)擊“OK”:123計(jì)算機(jī)工程學(xué)院③程序輸出結(jié)果如圖5-19所示。圖5-19案例7運(yùn)行結(jié)果124計(jì)算機(jī)工程學(xué)院5.歸納分析程序執(zhí)行時(shí)輸入Ex5_2_7123’456’78后,argc等于2,argv[0]指向字符串“Ex5_2_7”,argv[0]
指向字符串“123’456’78”。125計(jì)算機(jī)工程學(xué)院1.通過指針變量訪問一維數(shù)組元素一維數(shù)組的數(shù)組名表示該數(shù)組的首地址,它是一個(gè)常量。如果在其基礎(chǔ)上加上一個(gè)偏移量i,就表示向下第i個(gè)元素的地址。因此,在程序中定義一個(gè)指針變量使其指向數(shù)組首地址,然后對該指針變量進(jìn)行加減運(yùn)算,使其指向需要的數(shù)組元素,進(jìn)行讀寫訪問。根據(jù)以上敘述,引用一個(gè)數(shù)組元素可以用:
5.2.2基礎(chǔ)理論
126計(jì)算機(jī)工程學(xué)院
(1)下標(biāo)法,即用a[i]形式訪問數(shù)組元素。在前面介紹數(shù)組時(shí)都是采用這種方法。
(2)指針法,即采用*(p+i)形式,用間接訪問的方法來訪問數(shù)組元素,其中p是指向數(shù)組的指針變量,其初值p=a。定義指向數(shù)組元素的指針變量形式與定義指向變量的指針變量相同,如:
inta[10];int*p;p=a;/*或p=&a[0];*/127計(jì)算機(jī)工程學(xué)院這里應(yīng)當(dāng)注意指向數(shù)組元素的指針變量的類型必須要和數(shù)組類型保持一致。其中p和a有相同作用,只是a是常量,p是變量。執(zhí)行了p=a后:
(1)p+i和a+i就是a[i]的地址;(2)*(p+i)或*(a+i)都表示指向a[i];
128計(jì)算機(jī)工程學(xué)院2.使用指針變量訪問二維數(shù)組二維數(shù)組是若干個(gè)相同大小的一維數(shù)組的集合。二維數(shù)組的每一行都表示一個(gè)一維數(shù)組。因此二維數(shù)組中存在三類地址:數(shù)組首地址a、行地址a[i]和元素地址&a[i][j]。特別的,對于數(shù)組首行地址a[0],它的值與數(shù)組首地址相同,但含義不同,對它們進(jìn)行加減運(yùn)算的結(jié)果也不相同。例如:inta[3][4];int*p1=a+1;int*p2=a[0]+1;129計(jì)算機(jī)工程學(xué)院執(zhí)行后,p1指向數(shù)組a[1]行,而p2指向元素a[0][1]。因?yàn)閷τ赼來說,它是由a[0]、a[1]、a[2]三個(gè)行地址組成的一維數(shù)組的首地址,因此a+1表示在這個(gè)一維數(shù)組中下移一個(gè)元素:由指向a[0]變?yōu)橹赶騛[1]。而a[0]是二維數(shù)組首行指向的一維數(shù)組的首地址,因此對它加1表示在這個(gè)行數(shù)組中下移一個(gè)元素:由指向a[0][0]變?yōu)橹赶騛[0][1]。130計(jì)算機(jī)工程學(xué)院3.指向多維數(shù)組的指針變量
在C語言里,有一種指針變量是專門用來指向多維數(shù)組的,稱為“指向多維數(shù)組的指針變量”。我們可以通過“類型說明符(*指針變量名)[指向的一維數(shù)組的個(gè)數(shù)]”的形式來定義一個(gè)指向二維數(shù)組的指針變量。這樣,在對指針變量進(jìn)行加減操作時(shí),指針將在二維數(shù)組的行上移動(dòng)。
131計(jì)算機(jī)工程學(xué)院4.指針數(shù)組
數(shù)組元素是同一類型指針變量的數(shù)組稱為指針數(shù)組。與二維字符數(shù)組相比,指針數(shù)組用于處理多個(gè)字符串更方便。如果使用二維字符數(shù)組處理多個(gè)字符串,由于數(shù)組的列數(shù)是相同的,因此會(huì)造成存儲(chǔ)空間的浪費(fèi),而用指針數(shù)組就不存在這樣的問題。如圖5-20:132計(jì)算機(jī)工程學(xué)院(a)二維字符數(shù)組表示133計(jì)算機(jī)工程學(xué)院(b)指針數(shù)組表示圖5-20多字符串表示形式比較134計(jì)算機(jī)工程學(xué)院學(xué)習(xí)時(shí)要注意“指向多維數(shù)組的指針變量”和“指針數(shù)組”的差別:“指向多維數(shù)組的指針變量”是一個(gè)指針變量,它能夠指向數(shù)組,而“指針數(shù)組”是一個(gè)數(shù)組,它的元素是某一類型的指針。因此它們在定義、使用時(shí)都不一樣。135計(jì)算機(jī)工程學(xué)院5.使用指針變量處理字符串
字符串在內(nèi)存中是以字符數(shù)組的形式存儲(chǔ)的,因此所有對數(shù)組適用的技術(shù)都可以應(yīng)用到字符串上。使用時(shí)要注意兩點(diǎn):
(1)字符串可以看作是一個(gè)字符數(shù)組,因此使用指針變量處理字符串的時(shí)候,指針變量的類型要定義為char型;(2)字符串以’\0’結(jié)尾。因此可以通過當(dāng)前指針變量的內(nèi)容是否等于’\0’來判斷字符串是否結(jié)束。136計(jì)算機(jī)工程學(xué)院6.main函數(shù)的參數(shù)
main函數(shù)的參數(shù)值是從操作系統(tǒng)命令行上獲得的。它的參數(shù)有兩個(gè):整型的argc和指針數(shù)組argv。argc記錄了argv數(shù)組的元素個(gè)數(shù),argv以指向字符串的指針數(shù)組形式保存了命令行中輸入的文件名和參數(shù)列表。在輸入命令時(shí)文件名、參數(shù)列表都以空格作為分隔符。argv[0]指向文件名,argv[1]至argv[argc-1]分別指向參數(shù)1至參數(shù)n。137計(jì)算機(jī)工程學(xué)院7.指向指針的指針
由于指針變量也有地址,因此它也可以被其他指針變量指向。如果一個(gè)指針變量存放的是另一個(gè)指針變量的地址,則稱這個(gè)指針變量為指向指針的指針變量。定義一個(gè)指向指針的指針變量的語法為:
類型說明符**指針變量名;在前面已經(jīng)介紹過,通過指針訪問變量稱為間接訪問。由于指針變量直接指向變量,所以稱為“單級(jí)間址”。而如果通過指向指針的指針138計(jì)算機(jī)工程學(xué)院變量來訪問變量則構(gòu)成“二級(jí)間址”。例如:inta=4;
int*p1=&a;int**p2=&p1;
p1是一個(gè)指向整形變量a的指針變量,p2是一個(gè)指向p1的指針變量,如圖5-21所示:
139計(jì)算機(jī)工程學(xué)院圖5-21內(nèi)存示意圖140計(jì)算機(jī)工程學(xué)院
【實(shí)驗(yàn)5-3】下面的程序是用下標(biāo)法輸出數(shù)組的元素,分別根據(jù)要求完成編程:
(1)通過數(shù)組名計(jì)算元素的地址,輸出數(shù)組的元素。(2)用指針變量指向元素的方法,輸出數(shù)組的元素。
5.2.3技能訓(xùn)練
141計(jì)算機(jī)工程學(xué)院
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 關(guān)于股份分配的合同范本
- 外墻保溫設(shè)備租賃合同范本
- 租賃劃撥商業(yè)用地合同范本
- 入戶早教合同模板退費(fèi)協(xié)議
- 難點(diǎn)解析-魯教版(五四制)7年級(jí)數(shù)學(xué)下冊期末試卷完整附答案詳解
- 鄱陽縣人民醫(yī)院2025年招聘編外專業(yè)技術(shù)人員【84人】考前自測高頻考點(diǎn)模擬試題及答案詳解一套
- 難點(diǎn)解析-魯教版(五四制)7年級(jí)數(shù)學(xué)下冊期末試題及完整答案詳解(歷年真題)
- 期貨從業(yè)資格之《期貨法律法規(guī)》提分評估復(fù)習(xí)含答案詳解【b卷】
- 期貨從業(yè)資格之期貨投資分析復(fù)習(xí)提分資料及答案詳解(有一套)
- 期貨從業(yè)資格之《期貨法律法規(guī)》考試歷年機(jī)考真題集附答案詳解(黃金題型)
- 航天器再入軌道的實(shí)時(shí)監(jiān)測與數(shù)據(jù)處理技術(shù)-洞察闡釋
- 信息化項(xiàng)目監(jiān)理規(guī)劃
- TAOPA《固定式無人機(jī)反制設(shè)備技術(shù)規(guī)范》
- 新生兒院感管理
- 保潔用品采購管理制度
- 中國石油獨(dú)山子石化分公司32萬噸-年苯乙烯裝置擴(kuò)能改造項(xiàng)目環(huán)評報(bào)告
- 英語教師遴選試題及答案
- JG/T 2-2018鋼制板型散熱器
- 種植牙和解協(xié)議書
- 《大腦中動(dòng)脈解剖結(jié)構(gòu)》課件
- 2025-2030焦炭行業(yè)市場深度調(diào)研及發(fā)展規(guī)劃與投資前景研究報(bào)告
評論
0/150
提交評論