程序設(shè)計(jì)上課課件-第18講-疑難解答四_第1頁
程序設(shè)計(jì)上課課件-第18講-疑難解答四_第2頁
程序設(shè)計(jì)上課課件-第18講-疑難解答四_第3頁
程序設(shè)計(jì)上課課件-第18講-疑難解答四_第4頁
程序設(shè)計(jì)上課課件-第18講-疑難解答四_第5頁
已閱讀5頁,還剩44頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

疑難解答盤點(diǎn)知識(shí)點(diǎn),舉一反三地址與指針參數(shù)傳遞變量的

類別函數(shù)調(diào)用和宏調(diào)用共用體文件操作函數(shù)地址與指針地址…200120022003…3000…內(nèi)存單元的內(nèi)容…001000110001110111001100…00110011…CPUBUS指針嚴(yán)格地說,一個(gè)指針是一個(gè)地址,是一個(gè)常量。而一個(gè)指針變量卻可以被賦予不同的指針值,是變量。但常把指針變量簡稱為指針。為了避免,中約定:“指針”是指地址,是常量,“指針變量”是指取值為地址的變量。定義指針的目的是為了通過指針去內(nèi)存單元。指針定

義含

義inti;定義整型變量iint*p;p為指向整型數(shù)據(jù)的指針變量inta[n];定義整型數(shù)組a,它有n個(gè)元素int*p[n];指針數(shù)組p,由n個(gè)指向整型數(shù)據(jù)的指針元素組成int(*p)[n];p為指向含n個(gè)元素的一維數(shù)組的指針變量intf();f為帶回整型函數(shù)值的函數(shù)int*p();p為帶回一個(gè)指針的函數(shù),該指針指向整型數(shù)據(jù)int(*p)();p為指向函數(shù)的指針,該函數(shù)返回一個(gè)整型值int**p;p是一個(gè)指向一個(gè)指向整型數(shù)據(jù)的指針變量指針變量作為函數(shù)參數(shù)voidmain(){void

swap(int

*p1,int

*p2);inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);pointer_1=&a;pointer_2=&b;printf("\n%d,%d\n",*pointer_1,*pointer_2);if(a<b)

swap(pointer_1,pointer_2);printf("\n%d,%d\n",*pointer_1,*pointer_2);printf("\n%d,%d\n",a,b);getch();}void

swap(int

*p1,int*p2){int

temp;

temp=*p1;*p1=*p2;*p2=temp;}指針變量作為函數(shù)參數(shù)調(diào)用函數(shù):swap(x,

y);

被調(diào)用函數(shù):swap(int

*a,

int

*b)實(shí)參x形參xy59abxy59ab5

9調(diào)用時(shí)y59swap(x,y)swap(a,b)調(diào)用前調(diào)用后ab小結(jié)指針變量作形參時(shí),對(duì)應(yīng)實(shí)參為數(shù)據(jù)類型與該指針變量基類型相同的變量的地址。指針變量作形參時(shí),參數(shù)傳遞的形式仍然為值傳遞。調(diào)用函數(shù)時(shí),形參與對(duì)應(yīng)實(shí)參占據(jù)著不同的

空間,形參空間中存放的是對(duì)應(yīng)實(shí)參的地址。在函數(shù)調(diào)用過程中,通過對(duì)實(shí)參變量的間接訪問,改變了對(duì)應(yīng)實(shí)參的值。當(dāng)函數(shù)調(diào)用完畢后,形參的 空間仍然被收回,但此時(shí)實(shí)參空間中已經(jīng)保留了改變后的值,從而解決了在被調(diào)用函數(shù)中改變調(diào)用函數(shù)中變量的問題。參數(shù)傳遞形式參數(shù)又稱為形參或虛參,它表示一個(gè)函數(shù)被調(diào)用時(shí)所需的一些必要信息。事實(shí)上,形參是一種局部變量,它在函數(shù)被調(diào)用前并沒有被分配

空間,也沒有具體的值。形參僅僅是一個(gè)“符號(hào)”。實(shí)際參數(shù)又稱為實(shí)參,它是調(diào)用函數(shù)向被調(diào)用函數(shù)提供的一些具體信息,可以是常量、變量或表達(dá)式,它有具體的值。對(duì)于實(shí)參變量而言,它已經(jīng)被分配了相應(yīng)的

空間。調(diào)用有參函數(shù)時(shí),必須要提供與形參相匹配的實(shí)參。所謂匹配是指實(shí)參與形參的個(gè)數(shù)相等,對(duì)應(yīng)實(shí)參與

形參的類型相同或賦值兼容。參數(shù)傳遞在調(diào)用有參函數(shù)時(shí),系統(tǒng)將會(huì)根據(jù)形參的類型為其分配空間,而空間中的內(nèi)容即形參的值,則來自調(diào)用函數(shù)所提供的實(shí)參。當(dāng)被調(diào)用函數(shù)執(zhí)行完畢返回調(diào)用函數(shù)時(shí),形參的存儲(chǔ)空間又被系統(tǒng)收回,形參的值也就不復(fù)存在了。C語言中的參數(shù)傳遞通常是一種單向的“值傳遞”。當(dāng)實(shí)參為變量時(shí),函數(shù)調(diào)用時(shí)僅僅是將實(shí)參變量的值了一份交給形參形參與對(duì)應(yīng)實(shí)參的

空間完全不同,在函數(shù)調(diào)用過程中對(duì)形參的改變,根本不會(huì)影響到實(shí)參的值。函數(shù)調(diào)用與參數(shù)傳遞#include<stdio.h>void

swap(int

a,intb);

/*

函數(shù)原型*/voidmain(){ intx,y;x=10;

y=20;printf("Before

swap:x=%d

y=%d\n",x,y);swap(x,y); /*調(diào)用函數(shù)*/printf("After

swap :x=%d

y=%d\n",x,y);}void

swap(int

a,intb){ intt;t=a;

a=b;

b=t;函數(shù)調(diào)用與參數(shù)傳遞調(diào)用函數(shù):swap(x,

y);

被調(diào)用函數(shù):swap(int

a,int

b)實(shí)參x形參xy10

20abxy10

20ab10

20調(diào)用時(shí)y10

20abswap(x,y)swap(a,b)調(diào)用前調(diào)用后數(shù)組作為函數(shù)參數(shù)數(shù)值傳遞方式特點(diǎn):實(shí)參通過

的方式傳遞給形參(占用不同的內(nèi)存空間)調(diào)用函數(shù)的實(shí)參:給出具體數(shù)據(jù)實(shí)參地址

20

形參地址地址傳遞方式特點(diǎn):參數(shù)傳遞不是數(shù)據(jù)本身,而是數(shù)據(jù)的地址(使用同一地址空間)調(diào)用函數(shù)的實(shí)參:一般是數(shù)組名或指針變量實(shí)參地址20形參地址數(shù)組作為函數(shù)參數(shù)數(shù)組可以作為函數(shù)的參數(shù)使用,進(jìn)行數(shù)據(jù)傳送。數(shù)組用作函數(shù)參數(shù)有兩種形式:一種是把數(shù)組元素(下標(biāo)變量)作為實(shí)參使用;一種是把數(shù)組名作為函數(shù)的形參和實(shí)參使用。數(shù)組元素作函數(shù)實(shí)參數(shù)組元素:一個(gè)數(shù)組元素相當(dāng)于一個(gè)變量,所以,數(shù)組元素可以用于函數(shù)參數(shù),用法與變量相同。采用傳遞數(shù)據(jù)方式。數(shù)組作為函數(shù)參數(shù)數(shù)組元素就是下標(biāo)變量,它與普通變量并無區(qū)別。因此它作為函數(shù)實(shí)參使用與普通變量是完全相同的。在發(fā)生函數(shù)調(diào)用時(shí),把作為實(shí)參的數(shù)組元素的值傳送給形參,實(shí)現(xiàn)單向的值傳送。將數(shù)組元素當(dāng)作變量來作為實(shí)參使用傳值調(diào)用最多返回一個(gè)值數(shù)組作為函數(shù)參數(shù)(cont’d)判別一個(gè)整數(shù)數(shù)組中各元素的值,若大于0則輸出該值,若小于等于0

則輸出0值。void

nzp(int

v){if(v>0)

printf("%d

",v);else

printf("0");}main(){int

a[5],i;printf("Input

5

numbers:\n");for(i=0;i<5;i++)

{scanf("%d",&a[i]);

nzp(a[i]);}}數(shù)組作為函數(shù)參數(shù)用數(shù)組元素作實(shí)參時(shí),只要數(shù)組類型和函數(shù)的

形參變量的類型一致,那么作為下標(biāo)變量的數(shù)

組元素的類型也和函數(shù)形參變量的類型是一致

的。因此,并不要求函數(shù)的形參也是下標(biāo)變量。換句話說,對(duì)數(shù)組元素的處理是按普通變量對(duì)

待的。用數(shù)組名作函數(shù)參數(shù)時(shí),則要求形參和相對(duì)應(yīng)的實(shí)參都必須是類型相同的數(shù)組,都必須有明確的數(shù)組說明。當(dāng)形參和實(shí)參二者不一致時(shí),即會(huì)發(fā)生錯(cuò)誤。數(shù)組名作為函數(shù)參數(shù)在普通變量或下標(biāo)變量作函數(shù)參數(shù)時(shí),形參變量和實(shí)參變量是由編譯系統(tǒng)分配的兩個(gè)不同的內(nèi)存單元。在函數(shù)調(diào)用時(shí)發(fā)生的值傳送是把實(shí)參變量的值賦予形參變量。在用數(shù)組名作函數(shù)參數(shù)時(shí),不是進(jìn)行值的傳送,即不是把實(shí)參數(shù)組的每一個(gè)元素的值都賦予形

參數(shù)組的各個(gè)元素。因?yàn)閷?shí)際上形參數(shù)組并不

存在,編譯系統(tǒng)不為形參數(shù)組分配內(nèi)存。數(shù)組名作為函數(shù)參數(shù)數(shù)組作為函數(shù)參數(shù)=x[0]x[1]x[2]main(){void

fun(float

x[3]);floata[5]={3.5,

6.1,

0.2,

7.9};

int

i;fun(&a[1]);/*從第2個(gè)元素開始的連續(xù)3個(gè)地址*/for

(i=0;i<=4;i++)printf("%4.1f",

a[i]);getch();}voidfun(float

x[3]){x[0]+=1;

x[1]+=1;x[2]+a[0]

a[1]

a[2]

a[3]

a[4]兩個(gè)數(shù)組共享內(nèi)存空間3.57.11.28.90.0數(shù)組名就是數(shù)組的首地址。因此在數(shù)組名作

函數(shù)參數(shù)時(shí)所進(jìn)行的傳送只是地址的傳送,

也就是說把實(shí)參數(shù)組的首地址賦予形參數(shù)組

名。形參數(shù)組名取得該首地址之后,也就等

于有了實(shí)在的數(shù)組。實(shí)際上是形參數(shù)組和實(shí)

參數(shù)組為同一數(shù)組,共同擁有一段內(nèi)存空間。在變量作函數(shù)參數(shù)時(shí),所進(jìn)行的值傳送是單向的。即只能從實(shí)參傳向形參,不能從形參傳回實(shí)參。形參的初值和實(shí)參相同,而形參的值發(fā)生改變后,實(shí)參并不變化,兩者的終值是不同的。數(shù)據(jù)的傳送是如何實(shí)現(xiàn)的呢?而當(dāng)用數(shù)組名作函數(shù)參數(shù)時(shí),情況則不同。

由于實(shí)際上形參和實(shí)參為同一數(shù)組,因此當(dāng)

形參數(shù)組發(fā)生變化時(shí),實(shí)參數(shù)組也隨之變化。當(dāng)然這種情況不能理解為發(fā)生了“雙向”的

值傳遞。但從實(shí)際情況來看,調(diào)用函數(shù)之后

實(shí)參數(shù)組的值將由于形參數(shù)組值的變化而變

化。數(shù)據(jù)的傳送是如何實(shí)現(xiàn)的呢?void

nzp(inta[5]){int

i;

printf("\nValues

of

array

a

are:\n");for(i=0;i<5;i++)

{if(a[i]<0)

a[i]=0;

printf("%2d

",a[i]);}}main(){int

b[5]={1,-1,1,-1,1},i;printf("Initial

values

of

array

b

are:\n");for(i=0;i<nzp(b);printf("\nfor(i=0;i<}數(shù)組作為函數(shù)參數(shù)形參數(shù)組和實(shí)參數(shù)組的類型必須一致,否則將引起錯(cuò)誤。在函數(shù)形參表中,允許不給出形參數(shù)組的長度,或用一個(gè)變量來表示數(shù)組元素的個(gè)數(shù)。數(shù)組也可以作為函數(shù)的參數(shù)。在函數(shù)定義時(shí)對(duì)形參數(shù)組可以指定每一維的長度,也可省去第一維的長度。形參數(shù)組和實(shí)參數(shù)組的長度可以不相同,因?yàn)樵谡{(diào)用時(shí),只傳送首地址而

查形參數(shù)組的長度。當(dāng)形參數(shù)組的長度與實(shí)參數(shù)組不一致時(shí),雖不至于出現(xiàn)語法錯(cuò)誤(編譯能通過),但程序執(zhí)行結(jié)果將與實(shí)際不符,這是應(yīng)予以注意的。數(shù)組作為函數(shù)參數(shù)void

nzp(int

a[],

int

n){int

i;

printf("\nValues

of

array

a

are:\n");for(i=0;i<n;i++)

{if(a[i]<0)

a[i]=0;

printf("%2d

",a[i]);}}main(){int

b[5]={1,-1,1,-1,1},i;printf("Initial

values

of

array

b

are:\n");for(i=0;i<nzp(b,5);printf("\nfor(i=0;i<}數(shù)組作為函數(shù)參數(shù)void

nzp(int

a[8]){int

i;

printf("\nValues

of

array

a

are:\n");for(i=0;i<8;i++)

{if(a[i]<0)

a[i]=0;

printf("%2d

",a[i]);}}main(){int

b[5]printf("I<n<for(i=0;inzp(b);printf("\for(i=0;i}形參數(shù)組的長度與實(shí)參數(shù)組不一致數(shù)組a中的a[5]、a[6]、a[7]值沒有意義思考:若將形參數(shù)組長度由8改為4呢?變量的

類別用戶空間可以分為三個(gè)部分:動(dòng)態(tài)區(qū)靜態(tài)區(qū)程序區(qū)變量的

類別動(dòng)態(tài)區(qū)靜態(tài)區(qū)程序區(qū)在程序執(zhí)行過程中,靜態(tài)變量占據(jù)固定的單元,而不動(dòng)態(tài)地進(jìn)行分配和。全局變量全部存放在靜態(tài)區(qū),在程序開始執(zhí)行時(shí)給全局變量分配區(qū),程序行完畢就。變量的

類別動(dòng)態(tài)區(qū)靜態(tài)區(qū)程序區(qū)在函數(shù)開始調(diào)用時(shí)分配動(dòng)態(tài)空間,函數(shù)結(jié)束時(shí)這些空間。函數(shù)形式參數(shù);自動(dòng)變量(未加static的局部變量);函數(shù)調(diào)用時(shí)的現(xiàn)場保護(hù)和返回地址;靜態(tài)變量打印1

到5

的階乘值。intfac(intn){static

int

f=1;f=f*n;return(f);}main(){int

i;for(i=1;i<=5;i++)printf("%d!=%d\n",i,fac(i));}intfac(intn){intf=1;f=f*n;return(f);}main(){int

i;for(i=1;i<=5;i++)printf("%d!=%d\n",i,fac(i));}register

變量局部靜態(tài)變量不能定義為寄存器變量。intfac(intn){register

int

f=1;f=f*n;return(f);}main(){int

i;for(i=1;i<=5;i++)printf("%d!=%d\n",i,fac(i));}小結(jié)參數(shù)傳遞是一種單向的“值傳遞”。當(dāng)實(shí)參為變量時(shí),函數(shù)調(diào)用時(shí)僅僅是將實(shí)參變量的值復(fù)制了一份交給形參,形參與對(duì)應(yīng)實(shí)參的

空間完全不同,在函數(shù)調(diào)用過程中對(duì)形參的改變,根本不會(huì)影響到實(shí)參的值。但是在函數(shù)中對(duì)形參數(shù)組所做改變,將間接改變對(duì)應(yīng)實(shí)參數(shù)組。調(diào)用函數(shù)可能得到一個(gè)返回值外,當(dāng)需要返回多個(gè)數(shù)據(jù)時(shí),可以考慮使用數(shù)組參數(shù),或者通過全局變量在函數(shù)之間共享數(shù)據(jù),此外,通過靜態(tài)局部變量可以在同一函數(shù)前后兩次調(diào)用之間傳遞數(shù)據(jù)。帶參的宏與帶參函數(shù)不同SQ(int

y){return((y)*(y));}main(){int

i=1;while(i<=5)printf("%d\n",SQ(i++));}#define

SQ(y)((y)*(y))main(){int

i=1;while(i<=5)printf("%d\n",SQ(i++));}函數(shù)調(diào)用和宏調(diào)用輸入一個(gè)圓的半徑,輸出圓的面積。定義帶參數(shù)的宏S(r),程序如下:#define

PI

3.1415926535#define

S(r)PI*r*rvoidmain(){float

a=5.0,

area;area

=

S(a);printf("r=%f

area=%f\n",a,area);}可解決無參數(shù)宏定義中,替換字符串中含有其他字符,編譯時(shí)出現(xiàn)標(biāo)識(shí)符(變量)未定義錯(cuò)誤的情況。函數(shù)調(diào)用和宏調(diào)用函數(shù)調(diào)用宏調(diào)用信息傳遞實(shí)參的值或地址傳送給形參。用實(shí)參的字符串替換形參。內(nèi)存分配程序運(yùn)行時(shí)處理,分配臨時(shí)內(nèi)存單元。宏展開在預(yù)編譯時(shí)處理,不存在分配內(nèi)存的問題。參數(shù)類型實(shí)參和形參類型一致。如不一致,編譯器進(jìn)行類型轉(zhuǎn)換。作字符串替換,不存在參數(shù)類型問題。返回值可以有一個(gè)返回值。作字符串替換,不存在返回值問題。對(duì)源程序無影響。宏展開后使程序加長。時(shí)間占用占用程序運(yùn)行時(shí)間。占用編譯時(shí)間。共用體應(yīng)用舉例#include

"stdio.h"union

Ex{struct {int

x; inty;

}in;inta;intb;}e;main(){e.a=1;

e.b=2;e.in.x=e.a*e.b;

e.in.y=e.a+e.b;printf("%d\n",e.in.x);

printf("%d\n",e.in.y);getch();}共用體應(yīng)用舉例unionEx{struct{int

x;inty;}in;inta;intb;}e;共用體應(yīng)用舉例unionEx{struct{int

x;inty;}in;inta;intb;}e;e.in.x

e.in.y共用體應(yīng)用舉例unionEx{struct{int

x;inty;}in;inta;intb;}e;e.in.xe.in.ye.ae.be占多少個(gè)字節(jié)?共用體應(yīng)用舉例main(){e.a=1;e.b=2;e.in.x=e.a*e.b;e.in.y=e.a+e.b;printf("%d\n",e.in.x);printf("%d\n",e.in.y);getch();}e.in.xe.in.ye.ae.b共用體應(yīng)用舉例main(){e.a=1;e.b=2;e.in.x=e.a*e.b;e.in.y=e.a+e.b;printf("%d\n",e.in.x);printf("%d\n",e.in.y);getch();}e.in.x

e.in.ye.ae.b1112共用體應(yīng)用舉例main(){e.a=1;e.b=2;e.in.x=e.a*e.b;e.in.y=e.a+e.b;printf("%d\n",e.in.x);printf("%d\n",e.in.y);getch();}e.in.x

e.in.ye.ae.b224共用體應(yīng)用舉例main(){e.a=1;e.b=2;

e.in.x=e.a*e.b;e.in.y=e.a+e.b;printf("%d\n",e.in.x);printf("%d\n",e.in.y);getch();}e.in.x

e.in.ye.ae.b444共用體應(yīng)用舉例main(){e.a=1;e.b=2;

e.in.x=e.a*e.b;e.in.y=e.a+e.b;printf("%d\n",e.in.x);printf("%d\n",e.in.y);getch();}e.in.x

e.in.ye.ae.b484?共用體應(yīng)用舉例main(){e.b=2;e.a=1;e.in.x=e.a*e.b;e.in.y=e.a+e.b;printf("%d\n",e.in.x);printf("%d\n",e.in.y);getch();}e.in.x

e.in.ye.ae.b???數(shù)據(jù)輸入/輸出的概念數(shù)據(jù)輸入/輸出是相對(duì)計(jì)算機(jī)內(nèi)存從鍵盤將數(shù)據(jù)輸入從數(shù)據(jù)文件讀入將數(shù)據(jù)輸出到屏幕將數(shù)據(jù)輸出到文件CON:鍵盤或顯示器PRN:設(shè)備文件文件操作函數(shù)綜合示例函數(shù)原型功能返回值int

mkdir(const

char

*path)建立名稱由path指定的0:操作成功;-1:操作失敗FILE

*fopen(char

*fname,char*mode);以mode指定的方式打開指定文件成功,返回一個(gè)文件指針(文件信息區(qū)的起始地址);否則返回0int

fputs(char

*str,FILE

*fp);將str指向的字符串輸出到fp指定文件中0:操作成功;非0:操作失敗int

fclose(FILE

*fp);關(guān)閉fp指定的文件,文件緩沖區(qū)0:操作成功;非0:操作失敗int

rename(char

*oldname,char*newname);更改文件名0:操作成功;-1:操作失敗int

rmdir(char

*path);刪除path所指的0:操作成功;-1:操作失敗文件操作函數(shù)綜合示例#include

<stdio.h>voidmain(){FILE*fp;if(!mkdir("D:\\backup")){printf("Directory

D:\\backup

created!\n");getch();}else{printf("Unable

to

create

directory

D:\\backup!\n");getch();exit(1);}if(!mkdir("D:\\new")){printf("Directory

D:\\new

created!\n");getch();}else{printf("Unable

to

create

directory

D:\\new!\n");

getch();exit(1);}if((fp=fopen("D:\\backup\\old.txt","w"))==NULL){printf("File

could

not

be

opened!\n");getch();exit(1);}文件操作函數(shù)綜合示例if

(fputs("Wenzhou

University",fp)!=EOF){print

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論