ch07用函數(shù)實現(xiàn)模塊化程序設計10學時_第1頁
ch07用函數(shù)實現(xiàn)模塊化程序設計10學時_第2頁
ch07用函數(shù)實現(xiàn)模塊化程序設計10學時_第3頁
ch07用函數(shù)實現(xiàn)模塊化程序設計10學時_第4頁
ch07用函數(shù)實現(xiàn)模塊化程序設計10學時_第5頁
已閱讀5頁,還剩192頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第7章用函數(shù)實現(xiàn)模塊化程序設計函數(shù)是什么函數(shù)的定義和調用函數(shù)的嵌套調用和遞歸調用數(shù)組作為函數(shù)參數(shù)變量的作用域和生存期函數(shù)和外部函數(shù)提高部分27.1

函數(shù)是什么問題:如果程序的功能比較多,規(guī)模比較大,把所有的程序代碼都寫在一個主函數(shù)中,就會使主函數(shù)變得龐雜、頭緒不清,使閱讀和程序變得。37.1

函數(shù)是什么問題:有時程序中要多次實現(xiàn)某能,就需要多次重復編寫實現(xiàn)此功能的程序代碼。這使程序冗長,不精煉。457.1

函數(shù)是什么解決辦法:采用“組裝”的辦法簡化程序設計過程事先編好一批函數(shù),實現(xiàn)各種不同的功能用到什么函數(shù)就直接使用就可以這就是模塊化的程序設計67.1

函數(shù)是什么函數(shù)(function)就是功能每一個函數(shù)被用來實現(xiàn)一個特定的功能函數(shù)的名字應反映其代表的功能77.1

函數(shù)是什么在設計一個較大的程序時,往往把它分為若干個程序模塊,每一個模塊包括一個或多個函數(shù),每個函數(shù)實現(xiàn)一個特定的功能。一個C程序可由一個主函數(shù)和若干個其他函數(shù)構成。由主函數(shù)調用其他函數(shù),其他函數(shù)也可以互相調用。同一個函數(shù)可以被一個或多個函數(shù)調用任意多次。7.1

函數(shù)是什么mainabcfghdeie87.1

函數(shù)是什么可以使用庫函數(shù)可以使用自己編寫的函數(shù)在程序設計中要利用函數(shù),可以減少重復編寫程序段的工作量,同時可以方便地實現(xiàn)模塊化的程序設計9107.1

函數(shù)是什么例7.1

輸出以下的結果,用函數(shù)調用實現(xiàn)。******************How

do

you

do!******************117.1

函數(shù)是什么解題思路:在輸出的文字上下分別有一行“*”號,顯然不必重復寫這段代碼,用一個函數(shù)

print_star來實現(xiàn)輸出一行“*”號的功能。再寫一個print_message函數(shù)來輸出中間一行的文字信息用主函數(shù)分別調用這兩個函數(shù)#include

<stdio.h>int

main(){void

print_star();void

print_message();print_star();print_message();print_star();return

0;}void

print_star(){}輸出18個*printf("******************\n");輸出文字消息void

print_message(){printf("How

do

you

do!\n");}12#include

<stdio.h>int

main(){void

print_star();void

print_message();print_star();print_message();print_star();return

0;}void

print_star(){printf("******************\n");}函數(shù)函數(shù)定義void

print_message(){printf("How

do

you

do!\n");}1314說明:(1)一個C程序由一個或多個程序模塊組成,每一個程序模塊作為一個源程序文件。對于較大的程序,一般不把所有內容全放在一個源程序文件中,而是將它們分別放在若干個源文件中,由若干個源程序文件組成一個C程序。這樣便于分別編寫、分別編譯,提高調試效率。一個源程序文件可以為多個C程序所調用。說明:(2)一個源程序文件由一個或多個函數(shù)以及其他有關內容(如預處理指令、數(shù)據(jù)與定義等)組成。一個源程序文件是一個編譯單位,在程序編譯時是以源程序文件為單位進行編譯的,而不是以函數(shù)為單位進行編譯的。1516說明:(3)不論main函數(shù)出現(xiàn)在什么位置,總是從main函數(shù)開始執(zhí)行。如果在main函數(shù)中調用其他函數(shù),在調用后流程返回到main函數(shù),在main函數(shù)中結束整個程序的運行。17說明:(4)所有函數(shù)都是平行的,即在定義函數(shù)時是分別進行的,是互相獨立的。一個函數(shù)并不從屬于另一個函數(shù),即函數(shù)不能嵌套定義。函數(shù)間可以互相調用,但不能調用main函數(shù)。main函數(shù)是由系統(tǒng)調用的。18說明:(5)從用戶使用的角度看,函數(shù)有兩種。庫函數(shù),它是由系統(tǒng)提供的,用戶不必自己定義而直接使用它們。應該說明,不同的C語言編譯系統(tǒng)提供的庫函數(shù)的數(shù)量和功能會有一些不同,當然許多基本的函數(shù)是共同的。用戶自己定義的函數(shù)。它是用以解決用戶專門需要的函數(shù)。19說明:(6)從函數(shù)的形式看,函數(shù)分兩類。①無參函數(shù)。函數(shù)沒有參數(shù),一般用來執(zhí)行固定的一組操作。無參函數(shù)可以帶回或不帶回函數(shù)值,但一般以不帶回函數(shù)值的居多。②有參函數(shù)。在調用函數(shù)時,要給出實參。主調函數(shù)在調用被調用函數(shù)時,通過參數(shù)向被調用函數(shù)傳遞數(shù)據(jù),一般情況下,執(zhí)行被調用函數(shù)時會得到一個函數(shù)值,供主調函數(shù)使用。7.2

函數(shù)的定義和調用1.

為什么要定義函數(shù)函數(shù)定義函數(shù)的調用對被調用函數(shù)的和函數(shù)原型20217.2.1

為什么要定義函數(shù)C語言要求,在程序中用到的所有函數(shù),必須“先定義,后使用”指定函數(shù)名字、函數(shù)返回值類型、函數(shù)實現(xiàn)的功能以及參數(shù)的個數(shù)與類型,將這些信息通知編譯系統(tǒng)。227.2.1

為什么要定義函數(shù)指定函數(shù)的名字,以便以后按名調用指定函數(shù)類型,即函數(shù)返回值的類型指定函數(shù)參數(shù)的名字和類型,以便在調用函數(shù)時向它們傳遞數(shù)據(jù)指定函數(shù)的功能。這是最重要的,這是在函數(shù)體中解決的237.2.1

為什么要定義函數(shù)如果程序中要調用庫函數(shù),只需用#include指令把有關的頭文件包含到本文件模塊中即可。如果想使用庫函數(shù)中沒有的函數(shù),需要程序設計者在程序中自己定義。7.2.2

函數(shù)定義}包括

部分和語句部分1.怎樣定義無參函數(shù)函數(shù)名后的圓括號中為空,沒有參數(shù)定義無參函數(shù)的一般形式為:類型名

函數(shù)名(){

指定函數(shù)值的類型函數(shù)體247.2.2

函數(shù)定義1.怎樣定義無參函數(shù)函數(shù)名后的圓括號中為空,沒有參數(shù)定義無參函數(shù)的一般形式為:函數(shù)名()void{

表示函數(shù)沒有返回值函數(shù)體}25267.2.2

函數(shù)定義2.怎樣定義有參函數(shù)定義有參函數(shù)的一般形式為:類型名函數(shù)名(形式參數(shù)表列){函數(shù)體}7.2.2

函數(shù)定義2.怎樣定義有參函數(shù)int

max

(int

x,int

y){int

z;if(x>y)z=x;elsez=y;return

z;}函數(shù)的功能是什么?27287.2.2

函數(shù)定義定義空函數(shù)定義空函數(shù)的一般形式為:類型名函數(shù)名(

){

}先用空函數(shù)占一個位置,以后逐步擴充好處:程序結構清楚,可讀性好,以后擴充新功能方便,對程序結構影響不大7.2.3

函數(shù)的調用1.調用無參函數(shù)的形式函數(shù)名()如print_star()2.調用有參函數(shù)的形式函數(shù)名(實參表列)如max(a,b)如果有多個參數(shù),用逗號隔開2930例7.2輸入兩個整數(shù),輸出二者中的大者。要求在主函數(shù)中輸入兩個整數(shù),用一個函數(shù)max求出其中的大者,并在主函數(shù)中輸出此值。31解題思路:題目要求用一個max函數(shù)實現(xiàn)比較兩個整數(shù),并將得到的大數(shù)返回主函數(shù)。顯然,二個整數(shù)中的大者也應該是整數(shù),因此max函數(shù)應當是int型。兩個數(shù)是在主函數(shù)中輸入的,在max函數(shù)中進行比較,因此應該定義為有參函數(shù),在函數(shù)調用時進行數(shù)據(jù)的傳遞。int

max(int

x,int

y){int

z;if(x>y)函數(shù)類型 參數(shù)類型定義函數(shù)內使用的變量z=x;elsez=y;return

z;}32int

max(int

x,int

y){int

z;if(x>y)z=x;elsez=y;return

z;}3334#include

<stdio.h>int

main(){int

max(int

x,int

y);int

a,b,c;printf("please

input

two

numbers:");scanf("%d,%d",&a,&b);c

=

max(a,b);printf("max

is

%d\n",c);return

0;}int

max(int

x,int

y){int

z;if(x>y)z=x;elsez=y;return

z;}if(x>y)return

x;elsereturn

y;c

=

max(a,b);int

max

(int

x,int

y){int

z;if(x>y)z=x;elsez=y;return

z;}函數(shù)調用時的參數(shù)傳遞53#include

<stdio.h>int

main(){int

max(int

x,int

y);int

a,b,c;printf("please

input

two

numbers:");scanf("%d,%d",&a,&b);c

=

max(a,b);printf("max

is

%d\n",c);return

0;}int

max

(int

x

int

y){if(x>y)return

x;elsereturn

y;}函數(shù)調用時的參數(shù)傳遞實際參數(shù)形式參數(shù)36函數(shù)調用時的參數(shù)傳遞函數(shù)調用的過程:在函數(shù)定義中指定的形參,在未出現(xiàn)函數(shù)調用時,它們并不占內存中的單元。在發(fā)生函數(shù)調用時,函數(shù)的形參被臨時分配內存單元。并將實參的值

到相應的形參的內存單元中。abxy232337函數(shù)調用時的參數(shù)傳遞函數(shù)調用的過程:調用結束,形參單元被實參單元仍保留并維持原值,沒有改變如果在執(zhí)行一個被調用函數(shù)時,形參的值發(fā)生改變,不會改變主調函數(shù)的實參的值abxy23233839調用函數(shù)的方式按函數(shù)在程序中出現(xiàn)的位置來分,可以有以下3種函數(shù)調用方式1.函數(shù)語句調用沒有返回值的函數(shù),函數(shù)調用單獨作為一個語句如例7.1中的:print_star();40調用函數(shù)的方式按函數(shù)在程序中出現(xiàn)的位置來分,可以有以下3種函數(shù)調用方式2.函數(shù)表達式函數(shù)出現(xiàn)在一個表達式中,這種表達式稱為函數(shù)表達式如例7.2中的:c=max(a,b);41調用函數(shù)的方式按函數(shù)在程序中出現(xiàn)的位置來分,可以有以下3種函數(shù)調用方式3.函數(shù)參數(shù)函數(shù)調用作為一個函數(shù)的實參如:printf

(″%d″,

max

(a,b));7.2.4

對被調用函數(shù)的

和函數(shù)原型在一個函數(shù)中調用另一個函數(shù)需要具備如下條件:被調用函數(shù)必須是已經(jīng)定義的函數(shù)(是庫函數(shù)或用戶自己定義的函數(shù))。如果使用庫函數(shù),應該在本文件開頭加相應的#include指令。如果使用自己定義的函數(shù),而該函數(shù)的定義位置在調用它的函數(shù)后面,應該進行函數(shù)427.2.4

對被調用函數(shù)的型和函數(shù)原函數(shù)原型的一般形式有兩種:int

max(int

x,

int

y);int

max(int,

int);原型說明可以放在文件的開頭,這時本文件中所有函數(shù)都可以使用此函數(shù)43447.3

函數(shù)的嵌套調用和遞歸調用函數(shù)的嵌套調用函數(shù)的遞歸調用457.3.1

函數(shù)的嵌套調用調用一個函數(shù)的過程中,又可以調用另一個函數(shù)7.3.1

函數(shù)的嵌套調用main函數(shù)①調用a函數(shù)⑨結束a函數(shù)③調用b函數(shù)⑦②⑧b函數(shù)⑤④⑥4647例7.3輸入4個整數(shù),找出其中最大的數(shù)。用一個函數(shù)來實現(xiàn)。解題思路:定義max_4函數(shù),找4個數(shù)中最大者max_4中再多次調用max,找4個數(shù)中的大者,然后把它作為函數(shù)值返回main函數(shù)#include

<stdio.h>int

main(){int

max_4(int

a,

int

b,

int

c,

int

d);int

a,b,c,d,max;printf("4

integer

numbers:");scanf("%d%d%d%d",&a,&b,&c,&d);max=max_4(a,b,c,d);printf("max=%d

\n",max);return

0;}對max_4

函數(shù)48#include

<stdio.h>int

main(){int

max_4(int

a,

int

b,

int

c,

int

d);int

a,b,c,d,max;printf("4

integer

numbers:");scanf("%d%d%d%d",&a,&b,&c,&d);max=max_4(a,b,c,d);printf("max=%d

\n",max);return

0;}輸入4個整數(shù)49#include

<stdio.h>int

main(){int

max_4(int

a,

int

b,

int

c,

int

d);int

a,b,c,d,max;printf("4

integer

numbers:");scanf("%d%d%d%d",&a,&b,&c,&d);max=max_4(a,b,c,d);}printf("max=%d

\n",max);return

0;輸出最大者調用求4個數(shù)中最大的50int

max_4(int

a,int

b,int

c,int

d){int

max(int

a,int

b);int

m;m=max(a,b);m=max(m,c);m=max(m,d);return

m;}對max函數(shù)51int

max_4(int

a,int

b,int

c,int

d){int

max(int

a,int

b);int

m;m=max(a,b);m=max(m,c);m=max(m,d);return

m;}a,b中較大的a,b,c中較大的a,b,c,d中較大的52int

max_4(int

a,int

b,int

c,int

d){int

max(int

a,int

b);int

m;m=max(a,b);m=max(m,c);m=max(m,d);return

m;}a,b中較大的a,b,c中較大的a,b,c,d中較大的int

max

(int

x,int

y){if(x>y)return

x;elsereturn

y;}找x,y中較大的53int

max_4(int

a,int

b,int

c,int

d){int

max(int

a,int

b);int

m;m=max(a,b);m=max(m,c);m=max(m,d);return

m;}a,b中較大的a,b,c中較大的a,b,c,d中較大的int

max

(int

x,int

y){if(x>y)return

x;elsereturn

y;}return(x>y?x:y);54#include

<stdio.h>int

main(){int

max_4(int

a,

int

b,

int

c,

int

d);int

a,b,c,d,max;printf("4

integer

numbers:");scanf("%d%d%d%d",&a,&b,&c,&d);max=max_4(a,b,c,d);printf("max=%d

\n",max);return

0;}int

max_4(int

a,int

b,int

c,int

d){int

max(int

a,int

b);int

m;m=max(a,b);

m=max(m,c);

m=max(m,d);return

m;}int

max(int

x,int

y){return(x>y?x:y);}55#include

<stdio.h>int

max_4(int

a,

int

b,

int

c,

int

d);int

max(int

a,int

b);int

main(){int

a,b,c,d,max;printf("4

integer

numbers:");scanf("%d%d%d%d",&a,&b,&c,&d);max=max_4(a,b,c,d);printf("max=%d

\n",max);return

0;}int

max_4(int

a,int

b,int

c,int

d){int

m;m=max(a,b);m=max(m,c);m=max(m,d);return

m;}int

max(int

x,int

y){return(x>y?x:y);}56C語言規(guī)范

做法德羅斯特效應的得名于荷蘭著名品牌德羅斯特(Droste)可可粉的包裝盒。包裝盒上的圖案是一位護士拿著一個有及紙盒的托盤,而杯子及紙盒上的圖案和整張圖片相同。這張從1904年起開始使用,數(shù)十只進行了一些小幅的調整,后來成為一個家喻戶曉的概念。57

mons.wikimedia.

/wiki/File%3ADroste.jpg58http:/

/UEZWe.jpg工程師給孩子的睡前故事從前有個公司,公司里有個老工程師和小工程師,有一天,老工程師對小工程師說,從前有個公司,公司里有個老工程師和小工程師,有一天,老工程師對小工程師說,...,聽完這個故事你就會明白什么叫遞歸了,你知道故事了嗎?小工程師說,謝謝,聽完這個故事我就明白什么叫遞歸了。,聽完這個故事你就會明白什么叫遞歸了,你知道故事了嗎?小工程師說,謝謝,聽完這個故事我就明白什么叫遞歸了。7.3.2

函數(shù)的遞歸調用在調用一個函數(shù)的過程中又出現(xiàn)直接或間接地調用該函數(shù)本身,稱為函數(shù)的遞歸調用。C語言的特點之一就在于允許函數(shù)的遞歸調用。的兩個要素:遞歸程序最遞歸項遞歸結束條件60617.3.2

函數(shù)的遞歸調用#include

<stdio.h>int

sum(int

n);int

main(){int

num,add;printf("Enter

a

positiveinteger:\n");scanf("%d",&num);add=sum(num);printf("sum=%d",add);}int

sum(int

n){if(n==0)return

n;elsereturn

n+sum(n-1);/*對函數(shù)sum(int)的自我調用*/}7.3.2

函數(shù)的遞歸調用f2函數(shù)調用f1函數(shù)f函數(shù)調用f函數(shù)f1函數(shù)調用f2函數(shù)直接調用本函數(shù)間接調用本函數(shù)6263例7.6

有5個學生坐在一起問第5個學生多少歲?他說比第4個學生大2歲問第4個學生歲數(shù),他說比第3個學生大2歲問第3個學生,又說比第2個學生大2歲問第2個學生,說比第1個學生大2歲最后問第1個學生,他說是10歲請問第5個學生多大,就必須先知道第4個年解題思路:要求第5個齡要求第4個必須先知道第3個第3個

又取決于第2個第2個

取決于第1個每個學生

都比其前1個學生的

大264解題思路:age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=1065age(5)=age(4)+2

age(4)

=age(3)+2

age(3)

=age(2)+2

age(2)

=age(1)+2age(3)

=14age(2)=12

age(4)

=16age(5)=18age(1)

=10回溯階段遞推階段66age(5)=age(4)+2

age(4)

=age(3)+2

age(3)

=age(2)+2age(2)=age(1)+2age(2)=12age(3)

=14

age(4)

=16age(5)=18結束遞歸的條件age(1)

=10回溯階段遞推階段67#include

<stdio.h>int

age(int

n){printf("Computeint

c;if(n==1){c=10;of

Student

No.%d\n",n);printf("Age

of

Student

No.1

is

10\n");}else{c=age(n-1)+2;printf("Age

of

Student

No.%d

is

%d\n",n,c);}return

c;}int

main(){printf("%d\n",

age(5));return

0;}68age(5)輸出age(5)main函數(shù)c=age(4)+2age函數(shù)n=5c=age(3)+2age函數(shù)n=4c=age(1)+2c=age(2)+2c=10age(1)=1069age(2)=12age(3)=14age(4)=16age函數(shù)n=3age(5)=18age函數(shù)n=218age函數(shù)n=170例7.5

分別用遞推方法和遞歸方法求n!,即1×2×…×n。1.用遞推方法求n!解題思路:從1開始,乘2,再乘3……一直乘到n。這種方法容易理解,也容易實現(xiàn)。遞推法的特點是從一個已知的事實出發(fā),按一定規(guī)律推下一個事實,再從這個新的已知的事實出發(fā),再向下推出一個新的事實……這是和遞歸不同的。71#include

<stdio.h>int

main(){long

fac(int

n);int

n;long

result=0;

printf("input

an

integer:");scanf("%d",&n);result=fac(n);printf("%d!=%ld\n",n,result);return

0;}long

fac(int

n){int

i;long

result=1;for(i=1;i<=n;i++)result=result*i;return

result;}2.用遞歸方法求n!解題思路:遞歸的思路和遞推是相反的,并不是先求1再求1×2再×3…,直到×n,而是直接從目標出發(fā)提出問題:5!等于4!×5,而4!=3!×4…,而1!是已知的,不必再回溯了7273#include

<stdio.h>int

main(){long

fac(int

n);int

n;long

result;printf("input

an

integer:");scanf("%d",&n);

result=fac(n);printf(“%d!=%ld\n",n,result);return0;}long

fac(int

n){long

f;if(n<0)printf("n<0,data

error!");elseif(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}fac(5)輸出fac(5)main函數(shù)f=fac(4)×5fac函數(shù)n=5f=fac(3)×4fac函數(shù)n=4f=fac(1)×2f=fac(2)×3f=1fac(1)=174fac(2)=2fac(3)=6fac(4)=24fac函數(shù)n=3fac(5)=120fac函數(shù)n=2120fac函數(shù)n=175遞歸調用的特點:執(zhí)行“未知→未知→……遞歸邊界條件已知→已知→已知”的過程。76遞歸小結用遞歸方法解題的條件:(1)所求解的問題能轉化為用同一方法解決的子問題。子問題的規(guī)模比原問題的規(guī)模小。必須要有遞歸結束條件,停止遞歸,否則形成無窮遞歸,系統(tǒng)無法實現(xiàn)。777.4

數(shù)組作為函數(shù)參數(shù)數(shù)組元素作函數(shù)實參數(shù)組名作函數(shù)參數(shù)787.4.1

數(shù)組元素作函數(shù)實參由于實參可以是表達式,而數(shù)組元素可以是表達式的組成部分,因此數(shù)組元素可以作為函數(shù)的實參。例7.6有兩個運動隊a和b,各有10個隊員,每個隊員有一個綜

績。將兩個隊的每個隊員的成績按順序一一對應地逐個比較(即a隊第1個隊員與b隊第1個隊員比,……)。如果a隊隊員的成績高于b隊相應隊員成績的數(shù)目多于b隊隊員成績高于a隊相應隊員成績的數(shù)目(例如,a隊蠃6次,b隊蠃4次),則認為a隊勝。統(tǒng)計出兩隊隊員比較的結果(a隊高于、等于和低于b隊的次數(shù))。7980解題思路:設兩個數(shù)組a和b,各有10個元素,分別存放10個隊員的成績將兩個數(shù)組的相應元素逐個比較,用3個變量n,m,k分別累計a隊隊員高于、等于和低于b隊隊員的次數(shù)用一個函數(shù)higher來判斷每一次比較的結果,如果a隊員高于b隊員,結果為1,二者相等,結果為0,a隊員低于b隊員,結果為-1。最后比較n和k即可得到哪隊勝的結果81#include

<stdio.h>int

main(){int

higher(int

x,

int

y);int

a[10],b[10],i,n=0,m=0,k=0;printf("enter

array

a:\n");for(i=0;i<10;i++)scanf("%d",

&a[i]);printf("\n");printf("enter

array

b:\n");for(i=0;i<10;i++)scanf("%d",&b[i]);printf("\n");//輸入a隊隊員成績//輸入b隊隊員成績82for(i=0;i<10;i++){if(higher(a[i],b[i])==1)n++;else

if(higher(a[i],b[i])==0)m++;elsek=k+1;}printf("a

higher

than

b

%d

times\n",n);printf("a

equal

to

b

%d

times\n",m);printf("b

higher

than

a

%d

times\n”,k);//比較10個隊員//與變量作為實參一樣83if(n>k)printf("a

wins!\n");else

if

(n<k)printf("b

wins!\n");elseprintf("a

and

b

ties!\n");}84int

higher(int

x,

int

y){if(x>y)return

1;else

if(x<y)return

-1;elsereturn

0;}85問題擴展田忌賽馬如何在已知雙方成績的情況下,通過適當調整一方的隊員順序,取得最優(yōu)比賽結果?867.4.2

數(shù)組名作函數(shù)參數(shù)希望在函數(shù)中處理整個數(shù)組的元素時,可以用數(shù)組名作為函數(shù)實參注意,此時只是將數(shù)組的首元素的地址傳遞給所對應的形參,因此對應的形參應當是指針變量(見第8章)。87例7.7

有10個學生成績,用一個函數(shù)求全體學生的平均成績。解題思路:在主函數(shù)中定義一個實型數(shù)組score,將輸入的10個學生成績存放在數(shù)組中設計函數(shù)average,用來求學生平均成績需要把數(shù)組有關信息傳遞給average函數(shù)–采取用數(shù)組名作為實參,把數(shù)組地址傳給average函數(shù),在該函數(shù)中對數(shù)組進行處理88#include

<stdio.h>int

main(){float

average(float

array[10]);float

score[10],

aver;int

i;printf("input

10

scores:\n");for(i=0;i<10;i++)scanf("%f",&score[i]);aver=average(score);

//數(shù)組名作實參

printf("average

score

is%5.2f\n",aver);return

0;}float

average(float

array[10]){int

i;float

aver,

sum=array[0];for(i=1;i<10;i++)sum=sum+array[i];aver=sum/10;retur

;}//array與score共占同一

單元//實參、形參都是float型數(shù)組相當于

score[i]相當于

score[0]8990例7.8有兩個班,學生數(shù)不同,編寫一個函數(shù),用來分別求各班的平均成績。91解題思路:問題的關鍵是用同一個函數(shù)求不同人數(shù)的班級平均成績在定義形參時不指定大小,函數(shù)對不同人數(shù)的班級都是適用由于數(shù)組名傳遞的是數(shù)組首地址,可以利用同一個函數(shù)求人數(shù)不同的班平均成績在定義average函數(shù)時,增加一個參數(shù)n,用來指定當前班級的人數(shù)92#include

<stdio.h>int

main(){float

average(float

array[

],int

n);float

score_1[5]={98.5,97,91.5,60,55};float

score_2[10]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5};printf("%6.2f\n",

average(score_1,

5));printf("%6.2f\n",

average(score_2,

10));return

0;}sum=sum+array[i];aver=sum/n;retur

;float

average(float

array[],int

n){int

i;float

aver,

sum=array[0];for(i=1;i<n;i++)/*調用形式為average(score_1,5)時*/}相當于

score_1[0]相當于

score_1[i]n=593sum=sum+array[i];aver=sum/n;retur

;}相當于

score_2[0]相當于

score_2[i]n=10float

average(float

array[],int

n){int

i;float

aver,

sum=array[0];for(i=1;i<n;i++)/*調用形式為average(score_2,10)時*/94例7.9用一個函數(shù)實現(xiàn)用選擇法對10個整數(shù)按升序排列。解題思路:所謂選擇法就是先將10個數(shù)中最小的數(shù)與a[0]對換;再將a[1]到a[9]中最小的數(shù)與a[1]對換……每比較一輪,找出一個

排序的數(shù)中最小的一個共比較9輪95a[0]a[1]a[2]a[3]a[4]3694134961346996從小到大排序97#include

<stdio.h>void

selectionSort(int

array[],

int

n,int

order);void

printArray(int

array[],int

n);int

main(){int

array[]={70,60,50,40,30,20,10};printArray(array,7);selectionSort(array,7,1);printArray(array,7);return

0;}/*函數(shù)說明:將數(shù)組array的內容輸出到標準輸出參數(shù)說明:int

array[]待輸出的數(shù)組;int

n數(shù)組array的大小*/void

printArray(int

array[],int

n){int

i;for(i=0;i<n;i++)printf("%d

",array[i]);printf("\n");}/**函數(shù)說明:對數(shù)組array進行選擇排序,參數(shù)order用于指定排序結果為升序或降序參數(shù)說明:array待排序的整型數(shù)組;

n數(shù)組array的大小; order=0升序,1降序*/void

selectionSort(int

array[],int

n,int

order){int

i,j,select,tmp;for(j=0;j<n-1;j++){select=j;for(i=j;i<n-1;i++){if(order==0){//升序排序

if(array[select]>array[i+1])select=i+1;}else{//降序排序if(array[select]<array[i+1])select=i+1;}}//將array[j]與當前的最值array[select]交換if(j!=select){tmp=array[j];array[j]=array[select];array[select]=tmp;}else{printf("本輪不必交換\n");}}}在array[i]到array[n-1]中,找到最?。ㄗ畲螅?shù)的下標98在array[i]到array[n-1]中,將最?。ㄗ畲螅?shù)與array[i]交換99100例7.10有4個學生,5門課的成績,設計一個函數(shù),用來求出其中的最高成績。解題思路:–先使變量max的初值為二維數(shù)組中第一個元素的值,然后將二維數(shù)組中各個元素的值與max相比,每次比較后都把“大者”存放在max中,取代max的原值。全部元素比較完后,max

的值就是所有元素的最大值。101#include<stdio.h>int

main(){float

highest_score(float

array[4][5]);float

score[4][5]={{61,73,85.5,87,90},{72,84,66,88,78},{75,87,93.5,81,96},{65,85,64,76,71}};printf("%6.2f\n",highest_score(score));return

0;}102float

highest_score(float

array[4][5]){int

i,j;float

max;max=array[0][0];for(i=0;i<4;i++)for(j=0;j<5;j++)if(array[i][j]>max)max=array[i][j];return

max;}7.5

變量的作用域和生存期1.

變量的作用域-局部變量和全局變量變量的

方式和生存期作用域和生存期的小結1031047.5.1

變量的作用域——局部變量和全局變量1

局部變量在函數(shù)和復合語句內定義的變量,稱為內部變量或局部變量只在本函數(shù)或復合語句內范圍內有效(從定義點開始到函數(shù)或復合語句結束)在此函數(shù)或復合語句以外是不能使用這些變量的說明:主函數(shù)中定義的變量也只在主函數(shù)中有效,主函數(shù)也不能使用其他函數(shù)中定義的變量。不同函數(shù)中可以使用相同名字的變量,它們代表不同的對象,互不干擾。形式參數(shù)也是局部變量。在函數(shù)中可以使用本函數(shù)定義的形參,在函數(shù)外不能 它。在一個函數(shù) ,可以在復合語句中定義變量,這些變量只在本復合語句中有效。1051062

全局變量一個程序可以包含一個或若干個源程序文件(即程序模塊),而一個源文件可以包含一個或若干個函數(shù)在函數(shù)之外定義的變量是外部變量,也稱為全局變量(或全程變量)全局變量的有效范圍為從定義變量的位置開始到本源文件結束,在此范圍內可以為本文件中所有函數(shù)所共用2

全局變量在一個函數(shù)中既可以使用本函數(shù)中的局部變量,又可以使用有效的全局變量。如果在同一個源文件中,外部變量與局部變量同名,則在局部變量的作用范圍內,外部變量被“”了,即它不起作用,此時局部變量是有效的。107108例若外部變量與局部變量同名,分析結果。#include

<stdio.h>int

a=3,b=5;int

main(){int

max(int

a,int

b);int

a=8;printf("max=%d\n",

max(a,b));return

0;}int

max(int

a,int

b){return

a>b?a:b;}a為局部變量,僅在此函數(shù)內有效b為全局變量109#include

<stdio.h>int

a=3,b=5;int

main(){int

max(int

a,int

b);int

a=8;printf("max=%d\n",

max(a,b));return

0;}int

max(int

a,int

b){return

a>b?a:b;}a、b為局部變量,僅在此函數(shù)內有效111例7.11有4個學生,5門課的成績,要求輸出其中的最高成績以及它屬于第幾個學生、第幾門課程。112解題思路:在例7.10中,通過調用highest_score函數(shù),得到最高分除了輸出最高分以外,還要輸出該分數(shù)是屬于第幾個學生、笫幾門課的信息,即需要輸出3個結果調用一個函數(shù)只能得到一個函數(shù)值,因此例7.10程序無法解決這個問題可以使用全局變量,通過全局變量從函數(shù)中得到所需要的值113#include

<stdio.h>int

Row,Column;int

main(){float

highest_score(float

array[4][5]);float

score[4][5]={{61,73,85.5,87,90},{72,84,66,88,78},{75,87,93.5,81,96},{65,85,64,76,71}};float

h_score=highest_score(score);printf("The

highest

score

is

%6.2f\n",

h_score);printf("Student

No.is

%d\nCourse

No.

is

%d\n",

Row,

Column);return

0;}//定義全局變量114float

highest_score(float

array[4][5]){int

i,j;float

max;max=array[0][0];for(i=0;i<4;i++)for(j=0;j<5;j++)if(array[i][j]>max){max=array[i][j];Row=i;Column=j;}return

max;}//將行的序號賦給全局變量Row//將列的序號賦給全局變量Columnscoreh_score

Row

Columnarray

max

Row

Columnmain函數(shù)highest_score函數(shù)建議不在必要時不要使用全局變量115全局變量RowColumn實參—>形參返回值7.5.2

變量的方式和生存期變量的生存期:變量值存在的時間變量的兩種

方式:靜態(tài)

方式和動態(tài)方式靜態(tài)

方式是指在程序運行期間由系統(tǒng)分配固定的

空間的方式動態(tài)

方式是在程序運行期間根據(jù)需要進行動態(tài)的分配

空間的方式1167.5.2

變量的方式和生存期全局變量采用靜態(tài)

方式,在程序開始執(zhí)行時給全局變量分配

區(qū),程序執(zhí)行完畢。在程序執(zhí)行過程中它們占據(jù)固定的存儲單元,而不是動態(tài)地進行分配和

。1177.5.2

變量的方式和生存期在函數(shù)中定義的變量,在函數(shù)調用開始時分配動態(tài)

空間,函數(shù)結束時

這些空間。在程序執(zhí)行過程中,這種分配和

是動態(tài)的。1187.5.2

變量的方式和生存期每一個變量和函數(shù)都有兩個屬性:數(shù)據(jù)類型和數(shù)據(jù)的

類別數(shù)據(jù)類型,如整型、浮點型等類別指的是數(shù)據(jù)在內存中

的方式(如靜態(tài) 和動態(tài)

)119auto—

自動變量(auto變量)函數(shù)中的形參和在函數(shù)中定義的變量(包括在復合語句中定義的變量),都屬于此類在調用該函數(shù)時,系統(tǒng)給這些變量分配存儲空間,在函數(shù)調用結束時就自動這些空間。因此這類局部變量稱為自動變量。自動變量用關鍵字auto作類別的120int

f(int

a){auto

int

b,c=3;……}可以省略1212.static—

靜態(tài)變量以下情況需要指定static

類別:-

希望函數(shù)中的局部變量值在函數(shù)調用結束后不

而繼續(xù)保留原值,即其占用的存儲單元不

,在下一次該函數(shù)調用時,

該變量已有值,就是上一次函數(shù)調用結束時的值。這時就應用關鍵字static指定該局部變量為“靜態(tài)局部變量”。122123例7.12

輸出1到5的階乘值。解題思路:可以編一個函數(shù)用來進行一次累乘如第1次調用時進行1乘1第2次調用時再乘以2第3次調用時再乘以3依此規(guī)律進行下去這時希望上一次求出的連乘值保留,以便下一次再乘上一個數(shù)??梢杂胹tatic。#include

<stdio.h>int

main(){int

fac(int

n);int

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

i,

fac(i));return

0;}調用五次每調用一次,開辟新n,但f不是124int

fac(int

n){static

int

f=1;f=f*n;return

f;}#include

<stdio.h>int

main(){int

fac(int

n);int

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

i,

fac(i));return

0;}int

fac(int

n){static

int

f=1;f=f*n;return

f;}i=1:第一次調用1251f#include

<stdio.h>int

main(){int

fac(int

n);int

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

i,

fac(i));return

0;}int

fac(int

n){static

int

f=1;f=f*n;return

f;}i=2:第二次調用126f2#include

<stdio.h>int

main(){int

fac(int

n);int

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

i,

fac(i));return

0;}int

fac(int

n){static

int

f=1;f=f*n;return

f;}i=3:第三次調用127f6#include

<stdio.h>int

main(){int

fac(int

n);int

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

i,

fac(i));return

0;}int

fac(int

n){static

int

f=1;f=f*n;return

f;}i=4:第四次調用128f24#include

<stdio.h>int

main(){int

fac(int

n);int

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

i,

fac(i));return

0;}int

fac(int

n){static

int

f=1;f=f*n;return

f;}i=5:第五次調用129f120對靜態(tài)局部變量的說明:(1)靜態(tài)局部變量屬于靜態(tài)類別,在靜態(tài)區(qū)內分配單元。在程序整個運行期間都不。而自動變量(即動態(tài)局部變量)屬于動態(tài)

類別,占動態(tài)

區(qū)空間而不占靜態(tài)區(qū)空間,函數(shù)調用結束后即130131對靜態(tài)局部變量的說明:(2)對靜態(tài)局部變量是在編譯時賦初值的,即只賦初值一次,在程序運行時它已有初值。以后每次調用函數(shù)時不再重新賦初值而只是保留上次函數(shù)調用結束時的值。而對自動變量賦初值,不是在編譯時進行的,而是在函數(shù)調用時進行,每調用一次函數(shù)重新給一次初值,相當于執(zhí)行一次賦值語句。對靜態(tài)局部變量的說明:(3)如在定義局部變量時不賦初值的話,則對靜態(tài)局部變量來說,編譯時自動賦初值0(對數(shù)值型變量)或空字符(對字符變量)。而對自動變量來說,如果不賦初值則它的值是一個不確定的值。這是由于每次函數(shù)調用結束后單元已 ,下次調用時又重新另分配存儲單元,而所分配的單元中的值是不可知的。132對靜態(tài)局部變量的說明:(4)雖然靜態(tài)局部變量在函數(shù)調用結束后仍它的。因為它,而不能被其然存在,但其他函數(shù)是不能是局部變量,只能被本函數(shù)他函數(shù)。133對靜態(tài)局部變量的說明:(5)用靜態(tài)要多占內存(長期占用不釋放,而不能像動態(tài)那樣一個單元可供多個變量使用,節(jié)約內存),而且降低了程序的可讀性,當調用次數(shù)多時往往弄不清靜態(tài)局部變量的當前值是什么。因此,若非必要,不要多用靜態(tài)局部變量。134register—

寄存器變量一般情況下,變量(包括靜態(tài)方式和動態(tài)方式)的值是存放在內存中的寄存器變量允許將局部變量的值放在CPU中的寄存器中現(xiàn)在的計算機能夠識別使用頻繁的變量,從而自動地將這些變量放在寄存器中,而不需要程序設計者指定1354.extern—

外部變量的作用范圍(1)在一個文件內擴展外部變量的作用域如果外部變量不在文件的開頭定義,其有效的作用范圍只限于定義處到文件結束如果由于某種考慮,在定義點之前的函數(shù)需字extern對該變量作“外部變量要

該外部變量,則應該在

之前用關鍵”1364.extern—

外部變量的作用范圍(2)將外部變量的作用域擴展到其他文件在任一個文件中定義外部變量,而在另一文件中用extern對該變量作外部變量1377.5.3

作用域和生存期的小結對一個變量的屬性可以從兩個方面分析,一是變量的作用域,一是變量的生存期。前者是從空間的角度,后者是從時間的角度。二者有聯(lián)系但不是同一回事作用域:指在代碼的什么位置可以 該變量(復合語句內,函數(shù)內、文件內、任何位置)生存期:指在什么時間可以該變量(復合語句執(zhí)行時,函數(shù)執(zhí)行時、程序執(zhí)行時)138#include<stdio.h>int

a;int

main(

){…

f2();

… f1();

…}void

f1(){auto

int

b;…

f2();

…}void

f2(){static

int

c;…

…}//a的作用域//b的作用域//c的作用域

139文件:file1.ca生存期b生存期c生存期mainf2f1mainf2f1main140各種類型變量的作用域和存在性的情況變量

類別函數(shù)內函數(shù)外作用域存在性作用域存在性自動變量和寄存器變量∨∨╳╳靜態(tài)局部變量∨∨╳∨靜態(tài)外部變量∨∨∨(只限本文件)∨外部變量∨∨∨∨1417.6函數(shù)和外部函數(shù)函數(shù)外部函數(shù)1427.6.1函數(shù)如果一個函數(shù)只能被本文件中其他函數(shù)所調用,它稱為

函數(shù)。在定義

函數(shù)時,在函數(shù)名和函數(shù)類型的前面加static,即:static

類型名函數(shù)名(形參表)1437.6.1函數(shù)

函數(shù)又稱靜態(tài)函數(shù),因為它是用static聲明的通常把只能由本文件使用的函數(shù)和外部變量放在文件的開頭,前面都冠以static使之局部化,其他文件不能提高了程序的可靠性1441457.6.2

外部函數(shù)如果在定義函數(shù)時,在函數(shù)首部的最左端加關鍵字extern,則此函數(shù)是外部函數(shù),可供其他文件調用。如函數(shù)首部可以為extern

intfun

(inta,

int

b)-

如果在定義函數(shù)時省略extern,則默認為外部函數(shù)146例7.13有一個字符串,內有若干個字符,今輸入一個字符,要求程序將字符串中該字符刪去。用外部函數(shù)實現(xiàn)。j=0假設刪除空格,刪除空格的思路為Iamhappy\0……非空空

非空非空空

非空非空非空非空非空結束Iamhappy\0y\0……\0i=05814710#include

<stdio.h>int

main(){extern

void

enter_string(char

str[]);extern

void

delete_string(char

str[],

char

ch);extern

void

print_string(char

str[]);char

c,

str[81];printf("Input

string:");enter_string(str);printf("Input

the

char

to

be

removed:");scanf("%c",

&c);delete_string(str,c);print_string(str);return

0;}在本函數(shù)中將要調用的已在其他文件中定義的3個函數(shù)文件:rm_c.c148}149#include

<stdio.h>void

print_string(char

str[]){puts(str);}#include

<stdio.h>void

delete_string(char

str[],

char

ch){int

i,j=0;for(i=0;str[i]!='\0';i++){if(str[i]!=ch){str[j]=str[i];j++;}}str[j]='\0';}#include

<stdio.h>void

enter_string(char

str[81]){gets(str);文件:print_string.c文件:delete_string.c文件:enter_string.c1507.7

提高部分1.

實參求值的順序漢諾(Hanoi)塔問題算術運算測試-延伸1517.7.1

實參求值的順序如果實參表列包括多個實參,對實參求值的順序并不是確定的有的系統(tǒng)按自左至右順序求實參的值有的系統(tǒng)(如Turbo

C

2.0,

Turbo

C++3.0,VC++6.0)則按自右至左順序求值。152#include

<stdio.h>int

main(void){int

i=8;printf("%d

%d

%d

%d\n”,++i,++i,—i,--i);printf("%d\n”,i);return

0;}執(zhí)行結果是什么?操作系統(tǒng)編譯器執(zhí)行結果備注執(zhí)行后i值LinuxGCC8

8

8

899

9

97

8

7

8++i,++i,-

-i,-

-i++i,++i, i,-

-ii++,++i,i-

-,-

-i898Mac

OS

XLLVM編譯不通過Multiple

unsequencedmodifications

to'i'WindowsMSVC8

7

6

78

7

7

8++i,++i,-

-i,-

-i++i,i++,-

-i,i-

-88153漢諾塔問題(Tower

of

Hanoi)例7.8

Hanoi(漢諾)塔問題。古代有一個梵塔,塔內有3個座A、B、C,開始時A座上有64個盤子,盤子大小不等,大的在下,小的在上。有一個老和尚想把這64個盤子從A座移到C座,但規(guī)定每次只允許移動一個盤,且在移動過程中在3個座上都始終保持大盤在下,小盤在上。在移動過程中可以利用B座。要求:編程解n階漢諾塔問題,輸出移動盤子的步驟。漢諾塔問題(Tower

of

Hanoi)154http://w

mons/6/60/Tower_of_Hanoi_4.gif

mons/4/4f/Tower_of_Hanoi.gif/games/towerofhanoi.html四階漢諾塔三階漢諾塔ABC155解題思路:老和尚會這樣想:假

另外一個和尚能有辦法將上面63個盤子從一個座移到另一座。那么,問題就解決了。此時老和尚只需這樣做:(1)命令第2個和尚將63個盤子從A座移到B座(2)自己將1個盤子(最

的、最大的盤子)從A座移到C座(3)再命令第2個和尚將63個盤子從B座移到C座A

B

C156由上面的分析可知:將n個盤子從A座移到C座可以分解為以下3個步驟:(1)將A上n-1個盤借助C座先移到B座上把A座上剩下的一個盤移到C座上將n-1個盤從B座借助于A座移到C座上A

B

C157可以將第(1)步和第(3)步表示為:將“x”座上n-1個盤移到“y”座(借助“z”座)。在第(1)步和第(3)步中,x、y、z和A、B、C的對應關系不同。對第(1)步,對應關系是x對應A,y對應B,z對應C。對第(3)步,對應關系是x對應B,y對應C,z對應A。A

B

C158把上面3個步驟分成兩類操作:(1)將n-1個盤從一個座移到另一個座上(n>1)。這就是大和尚讓小和尚做的工作,它是一個遞歸的過程,即和尚將任務層層下放,直到第64個和尚為止。(2)將1個盤子從一個座上移到另一座上。這是大和尚自己做的工作。A

B

C159ABC將63個盤子從A移動到B第1個和尚的做法……160ABC將63個盤子從A移動到B第1個和尚的做法……161ABC將1個盤子從A移動到C第1個和尚的做法……162ABC將1個盤子從A移動到C第1個和尚的做法……163ABC將63個盤子從B移動到C第1個和尚的做法……164ABC將63個盤子從B移動到C第1個和尚的做法……165ABC將62個盤子從A移動到C第2個和尚的做法……166ABC將6

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論