C程序設(shè)計(jì)及工程案例分析-第5、6章 函數(shù);數(shù)組_第1頁(yè)
C程序設(shè)計(jì)及工程案例分析-第5、6章 函數(shù);數(shù)組_第2頁(yè)
C程序設(shè)計(jì)及工程案例分析-第5、6章 函數(shù);數(shù)組_第3頁(yè)
C程序設(shè)計(jì)及工程案例分析-第5、6章 函數(shù);數(shù)組_第4頁(yè)
C程序設(shè)計(jì)及工程案例分析-第5、6章 函數(shù);數(shù)組_第5頁(yè)
已閱讀5頁(yè),還剩199頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第5章

函數(shù)C程序設(shè)計(jì)及工程案例分析XX大學(xué):XX汽車主機(jī)廠與供應(yīng)商學(xué)習(xí)目標(biāo)了解結(jié)構(gòu)化程序設(shè)計(jì)的基本思想理解什么是函數(shù),為什么要使用函數(shù)會(huì)熟練使用函數(shù)的聲明、定義與調(diào)用會(huì)運(yùn)用調(diào)用函數(shù)時(shí)參數(shù)傳遞的規(guī)則了解函數(shù)的遞歸調(diào)用理解變量的作用范圍與生存期和變量的存儲(chǔ)類別目錄5.1什么是函數(shù)5.2函數(shù)的聲明、定義與調(diào)用5.3變量的作用域與生命周期5.4綜合應(yīng)用實(shí)例5.5工程案例分析什么是函數(shù)5.1一個(gè)大而復(fù)雜的設(shè)計(jì)任務(wù)按其主要功能分解為若干相對(duì)獨(dú)立的模塊確定好各模塊之間的調(diào)用關(guān)系和參數(shù)傳遞方式公共部分還可被提取出來作為獨(dú)立的公用模塊供團(tuán)隊(duì)在設(shè)計(jì)和實(shí)現(xiàn)其它模塊時(shí)調(diào)用可以將整個(gè)設(shè)計(jì)任務(wù)分解成小模塊,進(jìn)而分配給小組或個(gè)人最后再將它們的目標(biāo)模塊連接裝配成一個(gè)完整的整體應(yīng)有團(tuán)結(jié)協(xié)作意識(shí),同伴之間互相幫助各取所長(zhǎng),共同獲得更大成功5.1什么是函數(shù)?5.1什么是函數(shù)?一個(gè)完整的C語(yǔ)言程序有且只能有一個(gè)main函數(shù),C語(yǔ)言程序的基本構(gòu)成單位就是函數(shù)。從程序設(shè)計(jì)的角度看,函數(shù)就是一個(gè)自帶變量聲明和程序語(yǔ)句的程序模塊。C語(yǔ)言程序設(shè)計(jì)中,使用的函數(shù)通常有兩大類。第一類,標(biāo)準(zhǔn)庫(kù)函數(shù)。不同的C語(yǔ)言編譯器廠商根據(jù)C語(yǔ)言標(biāo)準(zhǔn)設(shè)計(jì)了為數(shù)眾多的庫(kù)函數(shù),其具體實(shí)現(xiàn)細(xì)節(jié)和執(zhí)行效率也不盡相同,常見的有進(jìn)行數(shù)學(xué)運(yùn)算的函數(shù)(如fabs\sin\cos\log等)、完成輸入輸出功能的函數(shù)(如printf\scanf\puts\gets等)、字符串處理函數(shù)等(詳情見附錄C);第二類,自定義函數(shù)。程序設(shè)計(jì)者根據(jù)問題分析和模塊劃分,自主設(shè)計(jì)完成的函數(shù)。5.1什么是函數(shù)?函數(shù)的運(yùn)用使得C語(yǔ)言程序的開發(fā)效率大幅度提高——把某個(gè)功能處理對(duì)應(yīng)的程序代碼封裝成一個(gè)函數(shù),后續(xù)的程序設(shè)計(jì)中如果用到了這個(gè)功能,直接調(diào)用這個(gè)封裝好的函數(shù)就可以了,不需要再重新去進(jìn)行這個(gè)功能的設(shè)計(jì)和編程實(shí)現(xiàn)了。如果在后續(xù)開發(fā)維護(hù)中,發(fā)現(xiàn)某個(gè)先前封裝好的函數(shù)可以有更好的實(shí)現(xiàn),則只需要在調(diào)用該函數(shù)的地方做極少的修改或不用做修改,只需把修改后的新函數(shù)和源代碼的其它部分一起重新編譯就可以完成程序的升級(jí)。C程序的基本組成單位、實(shí)現(xiàn)模塊化編程的是()。數(shù)組函數(shù)文件結(jié)構(gòu)體ABCD提交單選題10分函數(shù)的聲明、定義與調(diào)用5.25.2函數(shù)的聲明、定義與調(diào)用5.2函數(shù)的聲明、定義與調(diào)用程序5.1A是運(yùn)用之前學(xué)過的知識(shí)完成的程序,現(xiàn)在通過使用函數(shù)來重新編寫這個(gè)程序。程序5.1B編寫程序判別給定的正整數(shù)是否為素?cái)?shù)(使用函數(shù))#include<stdio.h>intisPrime(int

n);/*這行是函數(shù)isPrime的原型或聲明*/intmain(void){intm2=17,result;result=isPrime(m2);//函數(shù)的調(diào)用

if(result==1)printf("%disaprime

number.\n",m2);elseprintf("%disnotaprime

number.\n",m2);return0;}5.2函數(shù)的聲明、定義與調(diào)用程序5.1A是運(yùn)用之前學(xué)過的知識(shí)完成的程序,現(xiàn)在通過使用函數(shù)來重新編寫這個(gè)程序。程序5.1B編寫程序判別給定的正整數(shù)是否為素?cái)?shù)(使用函數(shù))/*以下是函數(shù)isPrime的定義*/intisPrime(intn){intm;//函數(shù)內(nèi)部聲明的變量

for(m=2;m<n;m++){if(n%m==0)return0;//函數(shù)中的返回值語(yǔ)句

}

return1;//函數(shù)中的返回值語(yǔ)句}5.2函數(shù)的聲明、定義與調(diào)用函數(shù)聲明使得編譯器可以先對(duì)函數(shù)進(jìn)行概要性預(yù)覽,以了解調(diào)用該函數(shù)時(shí)需要傳遞幾個(gè)參數(shù)和這些參數(shù)的類型。函數(shù)的完整定義(又叫做函數(shù)的實(shí)現(xiàn)或函數(shù)體)則在后續(xù)程序中再給出。函數(shù)的聲明類似于函數(shù)定義中的第一行,不同之處是需要其結(jié)尾處添加分號(hào)。程序5.1B中的第2行“intisPrime(intn);”就是一個(gè)函數(shù)聲明的范例。同樣,如果程序5.1B中的第2行修改為“intisPrime(int);”也是一個(gè)函數(shù)原型的范例。5.2函數(shù)的聲明、定義與調(diào)用定義add函數(shù)如下:floatadd(floatx,floaty){returnx+y;}下面四個(gè)選項(xiàng)中,錯(cuò)誤的函數(shù)聲明是(

)。floatadd(floatx,floaty)floatadd(float,float);floatadd(floata,floatb);floatadd(floatx,floata);ABCD提交單選題10分5.2函數(shù)的聲明、定義與調(diào)用圖5.1函數(shù)的定義及其要點(diǎn)圖示以下正確的函數(shù)形式是()doublefun(intx,inty){z=x+y;returnz;}fun(intx,y){intz;returnz;}fun(x,y){intx,y;doublez;z=x+y;returnz;}doublefun(intx,inty){doublez;z=x+y;returnz;}ABCD提交單選題10分5.2函數(shù)的聲明、定義與調(diào)用5.2.2形式參數(shù)與實(shí)際參數(shù)函數(shù)的形式參數(shù)(簡(jiǎn)稱“形參”)是指在函數(shù)聲明和函數(shù)定義時(shí)設(shè)定的參數(shù)。主要有兩個(gè)方面的作用:第一,形參是聯(lián)系函數(shù)外部和內(nèi)部的必要橋梁,形參的使用使得函數(shù)定義體能正常完成;第二,當(dāng)調(diào)用函數(shù)時(shí),形參起著重要的指示作用,讓函數(shù)調(diào)用者知道調(diào)用該函數(shù)時(shí)需要傳遞的參數(shù)的個(gè)數(shù)、順序和類型問題。程序5.1B的函數(shù)isPrime有一個(gè)形參,該形參的類型為int,該形參的名字為n,則說明調(diào)用該函數(shù)只能傳遞進(jìn)1個(gè)形參且類型須為int,此外n代表的是待判斷的正整數(shù),如果沒有參數(shù)則該函數(shù)無法正確完成。如果設(shè)計(jì)的某個(gè)函數(shù)確實(shí)不需要從外部傳遞參數(shù)給它,則該函數(shù)就是一個(gè)無形式參數(shù)的函數(shù)。無形式參數(shù)的函數(shù),可以在函數(shù)名后的括號(hào)里放上“void”關(guān)鍵字,也可以為空。函數(shù)的實(shí)際參數(shù)(簡(jiǎn)稱“實(shí)參”)是指在函數(shù)調(diào)用時(shí)傳遞給該函數(shù)的參數(shù),可以是一個(gè)變量、一個(gè)常量或一個(gè)表達(dá)式。函數(shù)調(diào)用的時(shí)候,只需要給出實(shí)參就可以了,不可以在實(shí)參的前面再加上數(shù)據(jù)類型的說明。5.2函數(shù)的聲明、定義與調(diào)用5.2.2形式參數(shù)與實(shí)際參數(shù)【例5.2】設(shè)計(jì)一個(gè)函數(shù)求三個(gè)數(shù)中的最小值并返回該最小值。程序5.2設(shè)計(jì)一個(gè)函數(shù)求三個(gè)數(shù)中的最小值并返回該最小值#include<stdio.h>

intmin_between3ints(inta,intb,intc){

intmin=a; if(b<min) min=b; if(c<min) min=c; returnmin;}5.2函數(shù)的聲明、定義與調(diào)用5.2.2形式參數(shù)與實(shí)際參數(shù)intmain(void){ inta,b,c;

printf("請(qǐng)按順序輸入3個(gè)整數(shù):\n");

printf("數(shù)a:");scanf("%d",&a);

printf("數(shù)b:");scanf("%d",&b);

printf("數(shù)c:");scanf("%d",&c);

printf("最小的數(shù)是:%d\n",min_between3ints(a,b,c)); return0;}5.2函數(shù)的聲明、定義與調(diào)用程序5.2運(yùn)行結(jié)果根據(jù)問題的描述,設(shè)計(jì)的函數(shù)需要有3個(gè)參數(shù)用于接收實(shí)際調(diào)用時(shí)要比較的3個(gè)數(shù),這里我們假定這3個(gè)數(shù)都是整數(shù),故函數(shù)形參的類型應(yīng)選取“int”,三個(gè)形參分別用變量a,b和c來命名函數(shù)內(nèi)部有一個(gè)用于存放臨時(shí)最小值的變量min,因此min_between3ints函數(shù)的形參變量a,b和c和內(nèi)部使用的變量min都是屬于函數(shù)min_between3ints的。函數(shù)執(zhí)行完畢后,得到的最小值存放在變量min中,因此只需要通過語(yǔ)句“returnmin;”就可把最終執(zhí)行的結(jié)果返回給該函數(shù)的調(diào)用者。5.2函數(shù)的聲明、定義與調(diào)用程序5.2運(yùn)行結(jié)果函數(shù)min_between3ints的形參和main函數(shù)內(nèi)聲明的變量a,b和c雖然名稱是相同的,但分別是不同的變量,它們各有自己獨(dú)立的內(nèi)存空間。main函數(shù)中調(diào)用了函數(shù)min_between3ints,因此main函數(shù)中聲明的變量a,b和c就是實(shí)際參數(shù)。函數(shù)min_between3ints在main中被調(diào)用時(shí),系統(tǒng)為它的3個(gè)形參和內(nèi)部使用的變量min分配空間,用來接收從實(shí)參傳遞過來的數(shù)值和函數(shù)內(nèi)部的運(yùn)算處理,當(dāng)函數(shù)min_between3ints的調(diào)用結(jié)束以后,系統(tǒng)會(huì)把調(diào)用函數(shù)時(shí)分配的空間全部收回.因此main中聲明的a,b和c這3個(gè)變量本身并沒有參與到該函數(shù)的實(shí)際執(zhí)行過程中來。5.2函數(shù)的聲明、定義與調(diào)用程序5.2運(yùn)行結(jié)果【例5.3】設(shè)計(jì)一個(gè)函數(shù)計(jì)算并返回一個(gè)數(shù)的正整數(shù)次冪。#include<stdio.h>doublepowofx(doublex,unsignedn){ doubley=1; unsignedi; for(i=1;i<=n;i++) y*=x; returny;}5.2函數(shù)的聲明、定義與調(diào)用程序5.2運(yùn)行結(jié)果【例5.3】設(shè)計(jì)一個(gè)函數(shù)計(jì)算并返回一個(gè)數(shù)的正整數(shù)次冪。intmain(void){doublea;unsignedn;printf("輸入數(shù)字:");scanf("%lf",&a);printf("輸入冪值:");scanf("%u",&n);printf("%lf的

%u次冪的值為:%lf\n",a,n,powofx(a,n));return0;}5.2函數(shù)的聲明、定義與調(diào)用程序5.2運(yùn)行結(jié)果根據(jù)問題的描述,設(shè)計(jì)的函數(shù)需要有2個(gè)參數(shù)分別用于接收實(shí)際調(diào)用時(shí)要計(jì)算的數(shù)和正整數(shù)次冪的值。這里設(shè)定要計(jì)算的數(shù)的數(shù)據(jù)類型為“double”,用“unsigned”型的變量來存儲(chǔ)正整數(shù)次冪。函數(shù)體內(nèi)部聲明了2個(gè)變量,分別用于存放最終的結(jié)果值和計(jì)算過程中的冪次計(jì)數(shù)。程序5.3main函數(shù)中的第5行代碼輸出最終的計(jì)算結(jié)果,第3組輸出格式“%lf”對(duì)應(yīng)的表達(dá)式為“powofx(a,n)”,說明如果一個(gè)函數(shù)有返回值,則該函數(shù)的調(diào)用可以作為函數(shù)參數(shù)出現(xiàn)。5.2函數(shù)的聲明、定義與調(diào)用5.2.3參數(shù)傳值的規(guī)則C語(yǔ)言函數(shù)調(diào)用時(shí)遵循的參數(shù)傳遞規(guī)則是:

實(shí)參的參數(shù)值單向地傳遞給形參變量隱含地說明,實(shí)際參數(shù)和形式參數(shù)有它們各自獨(dú)立的內(nèi)存空間,實(shí)參變量的數(shù)值被賦值給形參變量,實(shí)參變量本身并沒有參與到函數(shù)內(nèi)部代碼的執(zhí)行過程中。5.2函數(shù)的聲明、定義與調(diào)用5.2.3參數(shù)傳值的規(guī)則【例5.4】編寫函數(shù)交換2個(gè)變量的值。程序5.4編寫函數(shù)交換2個(gè)變量的值#include<stdio.h>voidswap(intm,intn);intmain(void){

inta=20,b=10; printf("a=%d,b=%d\n",a,b);

swap(a,b); printf("a=%d,b=%d\n",a,b); return0;}5.2函數(shù)的聲明、定義與調(diào)用5.2.3參數(shù)傳值的規(guī)則【例5.4】編寫函數(shù)交換2個(gè)變量的值。voidswap(intm,intn){ printf("m=%d,n=%d\n",m,n); intt=m;m=n;n=t; printf("m=%d,n=%d\n",m,n);}5.2函數(shù)的聲明、定義與調(diào)用程序5.4運(yùn)行結(jié)果這里出現(xiàn)一個(gè)問題:為什么調(diào)用函數(shù)后,main函數(shù)中變量a和b的值沒有改變呢?答案是(1)因?yàn)閙ain函數(shù)中調(diào)用函數(shù)swap時(shí),變量a和變量b是實(shí)際參數(shù),變量m和變量n是形式參數(shù);答案是(2)調(diào)用函數(shù)swap時(shí),系統(tǒng)會(huì)把第1實(shí)參變量a的值20傳遞給對(duì)應(yīng)的第1形參變量m,把第2實(shí)參變量b的值10傳遞給對(duì)應(yīng)的第2形參變量n,然后進(jìn)入函數(shù)swap內(nèi)部執(zhí)行相應(yīng)的語(yǔ)句,但變量a和變量b并沒有參與到函數(shù)swap的執(zhí)行過程中。5.2函數(shù)的聲明、定義與調(diào)用程序5.4運(yùn)行結(jié)果#include<stdio.h>voidswap(intx,inty){intz;z=x;

x=y;

y=z;}intmain(void){inta=3,b=8;swap(a,b);printf("%d,%d\n",a,b);return0;}3,88,33,38,8ABCD提交單選題10分以下關(guān)于函數(shù)敘述中,錯(cuò)誤的是(

)。函數(shù)未被調(diào)用時(shí),系統(tǒng)將不為形參分配內(nèi)存單元實(shí)參與形參的個(gè)數(shù)必須相等,且實(shí)參與形參的類型必須對(duì)應(yīng)一致當(dāng)形參是變量時(shí),實(shí)參可以是變量、常量或表達(dá)式如函數(shù)調(diào)用時(shí),實(shí)參與形參都為變量,則這兩個(gè)變量不可能占用同一內(nèi)存空間ABCD提交單選題10分5.2函數(shù)的聲明、定義與調(diào)用5.2.4函數(shù)中的返回值語(yǔ)句與函數(shù)的返回值函數(shù)返回值是一個(gè)函數(shù)在執(zhí)行完畢后向調(diào)用它函數(shù)或者系統(tǒng)反饋的一個(gè)值,這個(gè)值可以是各種數(shù)據(jù)類型?!l(shuí)調(diào)用了這個(gè)函數(shù),這個(gè)函數(shù)正確執(zhí)行完畢后的返回值就返回給誰(shuí);——在哪里調(diào)用這個(gè)函數(shù),這個(gè)函數(shù)的返回值就返回到哪里。5.2函數(shù)的聲明、定義與調(diào)用5.2.4函數(shù)中的返回值語(yǔ)句與函數(shù)的返回值【例5.5】編寫函數(shù)把指定的正整數(shù)n反向拼接得到一個(gè)新的正整數(shù)并返回,例如n=98765412,則經(jīng)過函數(shù)處理后應(yīng)返回21456789。程序5.5編寫函數(shù)把指定的正整數(shù)n反向拼接得到一個(gè)新的正整數(shù)并返回。intreverse(intn){ ints=0; while(n>0) { s=s*10+n%10; n=n/10; } returns;}5.2函數(shù)的聲明、定義與調(diào)用5.2.4函數(shù)中的返回值語(yǔ)句與函數(shù)的返回值【例5.5】編寫函數(shù)把指定的正整數(shù)n反向拼接得到一個(gè)新的正整數(shù)并返回,例如n=98765412,則經(jīng)過函數(shù)處理后應(yīng)返回21456789。程序5.5編寫函數(shù)把指定的正整數(shù)n反向拼接得到一個(gè)新的正整數(shù)并返回intmain(void){intm=98765412;intresult=reverse(m);printf("result=%d\n",result);return0;}5.2函數(shù)的聲明、定義與調(diào)用程序5.5運(yùn)行結(jié)果程序5.5中,reverse函數(shù)的作用就是把由形參n接收的正整數(shù)反向拼接得到一個(gè)新的正整數(shù)并返回。在main函數(shù)中的第2行調(diào)用了reverse函數(shù),那么reverse函數(shù)就應(yīng)在正確執(zhí)行完畢后,向第2行的調(diào)用位置處返回它執(zhí)行的結(jié)果21456789,這里n是形式參數(shù),m是實(shí)際參數(shù),調(diào)用reverse函數(shù)時(shí)把m的數(shù)值傳遞(或賦值)到變量n的內(nèi)存中。設(shè)計(jì)封裝一個(gè)函數(shù)時(shí)或調(diào)用一個(gè)函數(shù)時(shí),函數(shù)的返回值就是函數(shù)的類型。C語(yǔ)言中規(guī)定如果沒有明確指定一個(gè)函數(shù)的返回值類型,則該函數(shù)的返回值類型被缺省地設(shè)定為int;如果明確地知道一個(gè)函數(shù)執(zhí)行完畢就結(jié)束了,沒有或不需要返回值,則該函數(shù)的返回值類型須被明確設(shè)定為void。同時(shí)C語(yǔ)言也要求return語(yǔ)句中表達(dá)式的類型必須與指定的函數(shù)返回值的類型一致,否則要么編譯出錯(cuò),要么得到的返回值結(jié)果出錯(cuò)。5.2函數(shù)的聲明、定義與調(diào)用5.2.4函數(shù)中的返回值語(yǔ)句與函數(shù)的返回值【例5.6】編程輸出由字符構(gòu)成的,字符和圖案大小均可變的菱形圖案。5.2函數(shù)的聲明、定義與調(diào)用程序5.6編寫函數(shù)輸出由字符構(gòu)成的大小可變的菱形圖案#include<stdio.h>#include<stdio.h>voidPrintDiamond(intn,char

ch);voidPrintChar(intn,char

ch);intmain(void){

PrintDiamond(5,'*');return0;}5.2函數(shù)的聲明、定義與調(diào)用程序5.6編寫函數(shù)輸出由字符構(gòu)成的大小可變的菱形圖案voidPrintChar(intn,charch){for(inti=1;i<=n;i++)putchar(ch);}5.2函數(shù)的聲明、定義與調(diào)用voidPrintDiamond(intn,charch){for(inti=1;i<=n;i++)//菱形上半部分的輸出,使用封裝的函數(shù)PrintChar{ PrintChar(n-i,''); PrintChar(2*i-1,ch); PrintChar(1,'\n');}for(inti=1;i<n;i++)//菱形下半部分的輸出,使用for結(jié)合字符輸出函數(shù)putchar{ for(intk=1;k<=i;k++) putchar(''); for(intj=1;j<=2*(n-i)-1;j++) putchar(ch); printf("\n");}}5.2函數(shù)的聲明、定義與調(diào)用程序5.5運(yùn)行結(jié)果程序5.6中,我們封裝了2個(gè)函數(shù)PrintDiamond和PrintChar,這2個(gè)函數(shù)的作用就是用于輸出字符構(gòu)成的圖案或多個(gè)字符。因只用于進(jìn)行顯示,因此沒有必要返回結(jié)果,對(duì)于這種沒有返回值的函數(shù),我們把該函數(shù)的返回值類型聲明為void。如果去掉了PrintChar前的聲明和定義之前的“void”,C語(yǔ)言編譯器會(huì)認(rèn)為這個(gè)自定義函數(shù)的返回值類型為“int”,又由于該函數(shù)內(nèi)部并沒有返回一個(gè)int類型數(shù)值的返回值語(yǔ)句,故一些新標(biāo)準(zhǔn)的編譯器會(huì)報(bào)告該函數(shù)有語(yǔ)法錯(cuò)誤。5.2函數(shù)的聲明、定義與調(diào)用程序5.5運(yùn)行結(jié)果在PrintDiamond函數(shù)中,輸出菱形圖案上半部分的代碼里調(diào)用了函數(shù)PrintChar,輸出菱形圖案下半部分的代碼里采用了循環(huán)結(jié)合putchar函數(shù)的方法,相較之下,上半部分的代碼要簡(jiǎn)潔一些。main函數(shù)中調(diào)用了函數(shù)PrintDiamond,而在函數(shù)PrintDiamond中又調(diào)用了函數(shù)PrintChar和putchar,這種調(diào)用關(guān)系稱之為函數(shù)的嵌套調(diào)用。由此可見,實(shí)際參數(shù)與形式參數(shù)間的關(guān)系是變化的,在main函數(shù)中實(shí)參值分別為5和‘*’,此時(shí)形參為n和ch;然而在函數(shù)PrintDiamond的PrintChar(n-i,'');語(yǔ)句中,n則成了實(shí)參表達(dá)式的一部分。在C語(yǔ)言程序中,以下正確的描述是()。函數(shù)的定義可以嵌套,但函數(shù)的調(diào)用不可以嵌套函數(shù)的定義不可以嵌套,但函數(shù)的調(diào)用可以嵌套函數(shù)的定義和函數(shù)的調(diào)用均不可以嵌套函數(shù)的定義和函數(shù)的調(diào)用均可以嵌套ABCD提交單選題10分5.2函數(shù)的聲明、定義與調(diào)用C語(yǔ)言的函數(shù)返回值語(yǔ)句只能返回1個(gè)數(shù)值另外如果函數(shù)中有多個(gè)return語(yǔ)句,則也只能執(zhí)行其中的某1個(gè)return語(yǔ)句,具體執(zhí)行哪一個(gè)取決于函數(shù)代碼中的實(shí)際邏輯流程程序5.1B的isPrime函數(shù)中有2個(gè)return語(yǔ)句,不論該函數(shù)被調(diào)用多少次,這2個(gè)return語(yǔ)句也只能執(zhí)行其中的一個(gè)。后續(xù)學(xué)習(xí)中會(huì)討論間接的辦法“返回”多個(gè)數(shù)值。5.2函數(shù)的聲明、定義與調(diào)用【例5.7】設(shè)計(jì)一個(gè)圖形面積計(jì)算器,通過輸入1、2、3、4的數(shù)字選項(xiàng),分別計(jì)算圓形、三角形、矩形和梯形的面積,要求把計(jì)算4類圖形面積的方法封裝成4個(gè)函數(shù),并在main中測(cè)試這些函數(shù)。5.2函數(shù)的聲明、定義與調(diào)用程序5.7圖形面積計(jì)算器constdoublepi=3.1415926;/*計(jì)算圓的面積,r表示圓的半徑*/doublecircle(doubler){ returnpi*r*r;}/*計(jì)算三角形的面積,e和h分別表示三角形的底和高*/doubletriangle(doublee,doubleh){ returne*h/2;}5.2函數(shù)的聲明、定義與調(diào)用/*計(jì)算矩形的面積,w和h分別表示矩形的寬和高*/doublerectangle(doublew,doubleh){

returnw*h;}/*計(jì)算梯形的面積,e1和e2表示梯形的上底和下底,h表示高*/doubletrapezium(doublee1,doublee2,doubleh){

return(e1+e2)*h/2;}intmain(void){5.2函數(shù)的聲明、定義與調(diào)用程序5.5運(yùn)行結(jié)果intchoice;doubler,e,w,e1,e2,h;while(1){scanf("%d",&choice);if(choice<1||choice>4)break;switch(choice){case1:printf("請(qǐng)輸入圓的半徑");

scanf("%lf",&r);printf("半徑為%lf的圓面積為:%lf\n",r,circle(r));break;5.2函數(shù)的聲明、定義與調(diào)用 case2:printf("請(qǐng)輸入三角形的底和高");

scanf("%lf%lf",&e,&h);printf("底為%lf,高為%lf的三角形面積為:%lf\n",e,h,triangle(e,h));break;case3:printf("請(qǐng)輸入矩形的底和高");

scanf("%lf%lf",&w,&h);printf("寬為%lf,高為%lf的矩形面積為:%lf\n",w,h,rectangle(w,h));break;5.2函數(shù)的聲明、定義與調(diào)用 case4:printf("請(qǐng)輸入梯形的上底、下底和高");

scanf("%lf%lf%lf",&e1,&e2,&h);printf("上底為%lf,下底為%lf,高為%lf的梯形面積為:%lf\n",e1,e2,h,trapezium(e1,e2,h));break;}}return0;}5.2函數(shù)的聲明、定義與調(diào)用程序5.7設(shè)計(jì)封裝了4個(gè)函數(shù),每個(gè)函數(shù)的功能不一樣,各自設(shè)定的形式參數(shù)數(shù)量也不相同代碼中可以看到函數(shù)返回值語(yǔ)句是由return和1個(gè)表達(dá)式構(gòu)成的。C語(yǔ)言中的任何一個(gè)表達(dá)式都可以放在return語(yǔ)句當(dāng)中,只要能夠保證return后表達(dá)式的最終取值的類型和函數(shù)聲明(定義)時(shí)設(shè)定的函數(shù)返回值類型保持一致(或在賦值上是兼容的)即可。關(guān)于return的說法,錯(cuò)誤的是(

)。函數(shù)執(zhí)行時(shí)遇到return,不管其內(nèi)是否還有未執(zhí)行的代碼,都會(huì)結(jié)束函數(shù)調(diào)用;函數(shù)執(zhí)行時(shí)遇到return,會(huì)先執(zhí)行剩余的代碼后再結(jié)束函數(shù)調(diào)用函數(shù)中可以使用多個(gè)return;一個(gè)函數(shù)只能return一個(gè)值;ABCD提交單選題10分關(guān)于函數(shù)調(diào)用,以下說法正確的是(

)函數(shù)一定有返回值函數(shù)一定要有參數(shù)函數(shù)的參數(shù)能傳值,也能傳地址函數(shù)的參數(shù)傳值是從形參賦值給實(shí)參ABCD提交單選題10分以下程序運(yùn)行后屏幕輸出為(

)#include<stdio.h>intf(intx,inty){return(x+y);}main(){inta=2,b=3,c;c=f(a,b);printf("%d+%d=%d\n",a,b,c);}02+3=52+3=03+2=5ABCD提交單選題10分2函數(shù)的聲明、定義與調(diào)用5.2.5函數(shù)的遞歸調(diào)用所謂“遞歸”,從程序代碼的角度看就是“函數(shù)直接或間接調(diào)用函數(shù)自己”的現(xiàn)象。確切地說,遞歸實(shí)質(zhì)是種狀態(tài)求解方法之間有規(guī)律的轉(zhuǎn)移,程序員設(shè)計(jì)或定制函數(shù)來求解特定輸出時(shí)的狀態(tài),遞歸調(diào)用就成了從一些狀態(tài)求解函數(shù)到另一個(gè)狀態(tài)求解函數(shù)間的轉(zhuǎn)移過程,這個(gè)過程中體現(xiàn)出來的是函數(shù)自己直接或間接調(diào)用自己的現(xiàn)象。需要注意,使用遞歸必須封裝函數(shù)。函數(shù)的遞歸調(diào)用過程是在系統(tǒng)的控制下自動(dòng)一層一層深入進(jìn)行的(或展開的),直到滿足遞歸調(diào)用結(jié)束的條件,然后再逐層返回,或者由于進(jìn)程的??臻g被使用完畢,整個(gè)進(jìn)程都被操作系統(tǒng)終止。遞歸每深入一層,則屬于這個(gè)遞歸函數(shù)的局部變量就會(huì)由系統(tǒng)產(chǎn)生一份全新的副本(彼此有不同的內(nèi)存空間),盡管這些變量的名字是相同的。5.2函數(shù)的聲明、定義與調(diào)用5.2.5函數(shù)的遞歸調(diào)用遞歸的使用使得很多算法在編程實(shí)現(xiàn)時(shí)變得容易理解,絕大多數(shù)情況下遞歸的函數(shù)調(diào)用都可借助棧結(jié)構(gòu)改寫成非遞歸的形式。遞歸方便程序員編寫程序代碼,但給計(jì)算機(jī)增加了負(fù)擔(dān)。對(duì)問題得出的遞歸求解過程可以很方便的轉(zhuǎn)換為程序,其優(yōu)點(diǎn)就是易于理解和編程。函數(shù)的遞歸調(diào)用實(shí)際是通過棧機(jī)制實(shí)現(xiàn)的,每深入一層,都要占去一塊棧數(shù)據(jù)區(qū)域。對(duì)嵌套層數(shù)比較多的一些算法,遞歸會(huì)力不從心,可能會(huì)因可用內(nèi)存空間耗盡而使得程序運(yùn)行以崩潰告終,此外遞歸也可能造成大量的額外的CPU時(shí)間開銷。但是合理地使用遞歸能給實(shí)際編程帶來方便。5.2函數(shù)的聲明、定義與調(diào)用5.2.5函數(shù)的遞歸調(diào)用C程序設(shè)計(jì)語(yǔ)言中函數(shù)遞歸調(diào)用分為直接遞歸和間接遞歸。使用遞歸方法來解決問題,必須符合以下3個(gè)條件:第一,可以把要解決的問題轉(zhuǎn)化為一個(gè)新問題,而這個(gè)新的問題的解決方法仍與原來的解決方法相同,只是所處理的對(duì)象有規(guī)律地遞增或遞減。這里解決問題的方法相同指的是,調(diào)用函數(shù)的參數(shù)每次不同(有規(guī)律的遞增或遞減),如果沒有規(guī)律也就不能適用遞歸調(diào)用。第二,使用遞歸的方法可以很好地解決問題,或者說使問題能夠較為簡(jiǎn)單地解決,相比之下使用其它的辦法比較麻煩。第三,必定要有一個(gè)明確的結(jié)束遞歸的條件,即一定要能夠在適當(dāng)?shù)臈l件下結(jié)束遞歸調(diào)用,否則可能導(dǎo)致系統(tǒng)崩潰。一個(gè)遞歸算法必須包括(

)。遞歸部分終止條件和遞歸部分循環(huán)部分終止條件和循環(huán)部分ABCD提交單選題10分關(guān)于函數(shù)遞歸,下列說法不正確的是:在定義一個(gè)過程或函數(shù)時(shí)出現(xiàn)調(diào)用本過程或本函數(shù)的成分,稱之為遞歸。若調(diào)用自身,稱之為直接遞歸;若過程或函數(shù)p調(diào)用過程或函數(shù)q,而q又調(diào)用p,稱之為間接遞歸。一般地,一個(gè)遞歸模型是由遞歸出口和遞歸體兩部分組成,后者確定遞歸到何時(shí)結(jié)束。實(shí)際上遞歸的思路是把一個(gè)不能或者不好直接求解的“大問題”轉(zhuǎn)化為一個(gè)或者幾個(gè)“小問題”來解決。ABCD提交單選題10分遞歸函數(shù)最終會(huì)結(jié)束,那么這個(gè)函數(shù)一定(

)。使用了全局變量使用了全局變量或者使用了一個(gè)多個(gè)參數(shù)有一個(gè)分支不調(diào)用自身沒有循環(huán)調(diào)用ABCD提交單選題10分5.2函數(shù)的聲明、定義與調(diào)用5.2.5函數(shù)的遞歸調(diào)用【例5.8】用遞歸的方法求解n!。程序5.8用遞歸方式求解n!。

longf_n(longn){ if(n==1) return1; returnn*f_n(n-1);}intmain(void){ longm=6; printf("%ld!=%ld\n",m,f_n(m)); return0;}程序5.8運(yùn)行結(jié)果程序5.8設(shè)計(jì)函數(shù)longf_n(longn)以遞歸的方法求解n!。函數(shù)f_n用于求解任意整數(shù)的階乘,因此在函數(shù)f_n(longn)內(nèi)部可將求解過程等價(jià)轉(zhuǎn)換成n*f_n(n-1),原因在于n!=n*(n-1)!,而(n-1)!可通過函數(shù)調(diào)用f_n(n-1)來實(shí)現(xiàn)。遞歸調(diào)用的過程中我們只要處理好“原始問題”與“原始問題的第一層展開”之間的關(guān)系就好了,程序5.8函數(shù)f_n(longn)就是處理“原始問題”即求解n的階乘;語(yǔ)句n*f_n(n-1)則是處理“原始問題的第一層展開”,也即是進(jìn)行“狀態(tài)求解方法之間有規(guī)律的轉(zhuǎn)移”。程序5.8中,我們只完成了“原始問題”與“原始問題的第一層展開”,請(qǐng)一定記得在實(shí)際的執(zhí)行過程中,遞歸調(diào)用會(huì)在系統(tǒng)的控制下自動(dòng)的一層一層地展開,直到滿足條件n==1時(shí)“逐層展開”工作結(jié)束,然后再一層一層的返回。程序5.8的執(zhí)行過程如圖5.3所示。圖5.3程序5.8中f_n(6)的遞歸調(diào)用過程調(diào)用函數(shù)f(27)的輸出結(jié)果是(

)。voidf(intn){

if(n<5)printf("%d",n);else{printf("%d",n%5);f(n/5);}}1022012120ABCD提交單選題10分【例5.9】斐波那契數(shù)列中第n項(xiàng)值的計(jì)算過程。Fibonacci數(shù)列問題??????(??)=1,??=1????0??????(???1)+??????(???2),??>=2程序5.9斐波那契數(shù)列中第n項(xiàng)值。5.2函數(shù)的聲明、定義與調(diào)用longFib(longn){ if(n==1) return1; if(n==0) return1; returnFib(n-1)+Fib(n-2);}intmain(void){ longm=6;

printf("斐波那契數(shù)列中第%ld項(xiàng)的值為%ld\n",m,Fib(m)); return0;}程序5.9運(yùn)行結(jié)果

斐波那契數(shù)列中第6項(xiàng)的值為13程序5.9設(shè)計(jì)函數(shù)longFib(longn)以遞歸的方法求解斐波那契數(shù)列中第n項(xiàng),函數(shù)Fib用于求解斐波那契數(shù)列中第n項(xiàng)。結(jié)合問題描述,在函數(shù)Fib(longn)內(nèi)部可將求解過程等價(jià)轉(zhuǎn)換成Fib(n-1)+Fib(n-2),而斐波那契數(shù)列中第n-1項(xiàng)和第n-2項(xiàng)可分別通過函數(shù)調(diào)用Fib(n-1)和Fib(n-2)來實(shí)現(xiàn)。遞歸調(diào)用的過程中,只要處理好“原始問題”與“原始問題的第一層展開”之間的關(guān)系就好了,函數(shù)Fib(longn)就是處理“原始問題”即求解斐波那契數(shù)列中第n項(xiàng);語(yǔ)句Fib(n-1)+Fib(n-2)則是處理“原始問題的第一層展開”,也即是進(jìn)行“狀態(tài)求解方法之間有規(guī)律的轉(zhuǎn)移”。程序5.9只完成了“原始問題”與“原始問題的第一層展開”,請(qǐng)一定記得在實(shí)際的執(zhí)行過程中,遞歸調(diào)用會(huì)在系統(tǒng)的控制下自動(dòng)的一層一層地展開,直到滿足條件“n==1”或“n==0”時(shí)“逐層展開”工作結(jié)束,然后再一層一層的返回?!纠?.10】漢諾塔問題的求解。印度有一個(gè)古老的傳說:在世界中心貝拿勒斯(位于印度北部)的圣廟里,一塊黃銅板上插著三根寶石針。印度教的主神大梵天在創(chuàng)造世界的時(shí)候,在其中一根針上從下到上地穿好了由大到小的64片圓盤,這就是漢諾塔。不論白天黑夜,總有一個(gè)僧侶在按照下面的法則移動(dòng)這些圓盤:一次只移動(dòng)一片,不管在哪根針上,小盤必須在大盤上面。僧侶們預(yù)言,當(dāng)所有的圓盤都從梵天穿好的那根針上移到另外一根針上時(shí),而梵塔、廟宇和眾生也都將在一聲霹靂中飛灰煙滅,世界末日就到了。漢諾塔如圖5.5所示。voidMovePlate(charM,charN)//表示把M桿上的盤子移動(dòng)到N桿上{

printf("Moveaplatefrompillar%ctopillar%c\n",M,N);}voidhanoi(intn,charA,charB,charC)/*將n個(gè)盤從A桿借助B桿,移到C桿*/{

if(n==1) MovePlate(A,C);//把A桿上的盤子移動(dòng)到C桿上

else{ hanoi(n-1,A,C,B); MovePlate(A,C); hanoi(n-1,B,A,C); }}程序5.10運(yùn)行結(jié)果

Moveaplatefrompillar1topillar3

Moveaplatefrompillar1topillar2

Moveaplatefrompillar3topillar2

Moveaplatefrompillar1topillar3

Moveaplatefrompillar2topillar1

Moveaplatefrompillar2topillar3

Moveaplatefrompillar1topillar3要解決漢諾塔問題,首先考慮A桿下面的盤子而非桿上最上面的盤子,于是任務(wù)變成了:將上面的63個(gè)盤子移到B桿上;將A桿上剩下的盤子移到C桿上;將B桿上的全部盤子移到C桿上。將這個(gè)過程繼續(xù)下去,就是要先完成移動(dòng)63個(gè)盤子、62個(gè)盤子、61個(gè)盤子……的工作。于是N層漢諾塔上的N個(gè)盤子從A桿上借助C桿移動(dòng)到B桿上,整個(gè)移動(dòng)工作就可以按照以下過程進(jìn)行:(1)把A桿上面的n-1個(gè)盤子借助B桿移動(dòng)到C桿上;(2)把A桿上的盤子從A桿移動(dòng)到B桿上;(3)把第1步移到C桿上的n-1個(gè)盤子借助A桿移動(dòng)到B桿上;重復(fù)以上過程,直到將全部的盤子移動(dòng)到位時(shí)為止。函數(shù)voidhanoi(intn,charA,charB,charC)用來完成“把放在A桿上的n個(gè)盤子借助B桿放在C桿上”,這個(gè)工作可以按上述的分析方案來完成,方案中的步驟1和3可通過調(diào)用函數(shù)voidhanoi(intn,charA,charB,charC)來進(jìn)行,只不過相應(yīng)的函數(shù)參數(shù)要分別改變?yōu)椋?/p>

hanoi(n-1,A,C,B);//把A桿上面的n-1個(gè)盤子借助C桿移動(dòng)到B桿上;和

hanoi(n-1,B,A,C);//把B桿上面的n-1個(gè)盤子借助A桿移動(dòng)到C桿上;其實(shí)上面兩個(gè)語(yǔ)句就是在處理“原始問題”與“原始問題的第一層展開”之間的關(guān)系。函數(shù)voidMovePlate(charM,charN)則是完成功能:“某桿上原本有n個(gè)盤子,該桿上面的n-1個(gè)被移走后,把該桿上剩的那個(gè)最大的盤子移動(dòng)到另外2根桿子中的那個(gè)空桿上”。程序5.10仍然是只完成了“原始問題”與“原始問題的第一層展開”,請(qǐng)一定記得在實(shí)際的執(zhí)行過程中,遞歸調(diào)用會(huì)在系統(tǒng)的控制下自動(dòng)的一層一層地展開,直到滿足條件“n==1”時(shí)“逐層展開”工作結(jié)束,即調(diào)用函數(shù)MovePlate。以下關(guān)于函數(shù)的敘述中,不正確的是(

)。函數(shù)必須定義,后調(diào)用函數(shù)可以遞歸調(diào)用函數(shù)可以嵌套調(diào)用每個(gè)函數(shù)都可以被其它函數(shù)調(diào)用ABCD提交單選題10分下列敘述中正確的是(

)函數(shù)的定義不能嵌套,但函數(shù)調(diào)用可以嵌套函數(shù)的定義可以嵌套,但函數(shù)調(diào)用不能嵌套函數(shù)的定義和調(diào)用都不能嵌套函數(shù)的定義和調(diào)用都可以嵌套ABCD提交單選題10分變量的作用域與生命周期5.35.3變量的作用域與生命周期通常來說,一段程序代碼所用到的變量并不總是有效的、可用的,限定這個(gè)變量可用性的代碼范圍就是這個(gè)變量的作用域。變量的生命周期是指變量從創(chuàng)建到銷毀之間的一個(gè)時(shí)間段。這兩個(gè)概念,前一個(gè)是從空間的角度描述變量,后一個(gè)是從時(shí)間的角度描述變量。5.3變量的作用域與生命周期5.3.1全局變量和局部變量C語(yǔ)言變量根據(jù)起作用的范圍分為全局變量與局部變量。全局變量是指在函數(shù)之外聲明的變量,聲明全局變量的時(shí)候如果沒有給該變量賦初值,則其初值自動(dòng)初始化為0,全局變量一旦聲明則在整個(gè)程序運(yùn)行期間都有效,即從聲明位置開始直到整個(gè)源文件結(jié)尾都可以使用。局部變量就是聲明在函數(shù)內(nèi)部的變量,通常有3種形態(tài):(1)函數(shù)的形式參數(shù)(2)函數(shù)體內(nèi)部聲明的變量(3)函數(shù)體內(nèi)部復(fù)合語(yǔ)句中聲明的變量局部變量只有當(dāng)其所屬的函數(shù)或所屬的復(fù)合語(yǔ)句被調(diào)用時(shí),系統(tǒng)為它們分配內(nèi)存空間,當(dāng)它們所屬的復(fù)合語(yǔ)句或者所屬的函數(shù)調(diào)用結(jié)束時(shí),系統(tǒng)分配給局部變量的空間就會(huì)被收回,局部變量的作用范圍不能延伸到其所屬的范圍之外。包含局部變量的函數(shù)返回以后,局部變量的值是無法繼續(xù)保留的,當(dāng)再次調(diào)用該函數(shù)時(shí),無法保證變量仍然擁有該函數(shù)前次調(diào)用結(jié)束時(shí)的值。5.3變量的作用域與生命周期5.3.1全局變量和局部變量程序代碼執(zhí)行的過程中,當(dāng)前范圍內(nèi)聲明的局部變量?jī)?yōu)先,也就是說如果有外部的變量和當(dāng)前范圍內(nèi)的某個(gè)變量同名,則此刻當(dāng)前范圍內(nèi)的變量起作用?!纠?.11】全局變量與局部變量的區(qū)別。程序5.11全局變量與局部變量#include<stdio.h>intm=10,n=20;voidprocess_data(){

intm=30; { intm=40,n=50; printf("m=%d,n=%d\n",m,n); } printf("m=%d,n=%d\n",m,n);}5.3變量的作用域與生命周期5.3.1全局變量和局部變量intmain(void){printf("m=%d,n=%d\n",m,n);process_data();return0;}5.3變量的作用域與生命周期程序5.11全局變量與局部變量程序5.11中,main函數(shù)的第1行語(yǔ)句輸出變量m和n的值,但main沒有聲明變量m和n,則此時(shí)使用的變量就是程序5.11中第2行里聲明的全局變量m和n(第一行輸出語(yǔ)句:m=10,n=20)。process_data函數(shù)最后1行語(yǔ)句輸出變量m和n的值,process_data函數(shù)里第1行語(yǔ)句只聲明了變量m,沒有聲明變量n,故最后1行的語(yǔ)句中使用的變量m就是在process_data函數(shù)中聲明的變量m,且其初值為30,使用的變量n則是全局變量n,其值為20(最后一行輸出語(yǔ)句:m=30,n=20)。5.3變量的作用域與生命周期程序5.11全局變量與局部變量process_data函數(shù)內(nèi)部有1個(gè)復(fù)合語(yǔ)句(用“{}”括起來的語(yǔ)句),且在該復(fù)合語(yǔ)句中聲明了變量m和n,同時(shí)其初值分別為40和50,故復(fù)合語(yǔ)句里的最后一條語(yǔ)句輸出變量m和n的值時(shí),所使用的變量就是復(fù)合語(yǔ)句中聲明的變量m和n(第二行輸出語(yǔ)句:m=40,n=50)。如果把復(fù)合語(yǔ)句中聲明變量m和n的語(yǔ)句去掉,則復(fù)合語(yǔ)句中使用的變量m就是process_data函數(shù)中第1行聲明的變量m,由于process_data函數(shù)內(nèi)沒聲明,調(diào)用process_data函數(shù)的main函數(shù)中也沒有聲明,故此時(shí)的變量n就是全局變量n。process_data函數(shù)內(nèi)復(fù)合語(yǔ)句中去掉變量m和n的聲明后,運(yùn)行結(jié)果如下:

m=10,n=20

m=30,n=20

m=30,n=205.3變量的作用域與生命周期5.3.2變量的存儲(chǔ)類別變量的存儲(chǔ)類別常用的有:自動(dòng)、靜態(tài)、外部與寄存器類型。C語(yǔ)言中聲明一個(gè)變量的完整形式如下:5.3變量的作用域與生命周期5.3.2變量的存儲(chǔ)類別表5.1C語(yǔ)言中自動(dòng)類型和靜態(tài)類型變量的存儲(chǔ)期【例5.12】靜態(tài)類型變量的使用程序5.12靜態(tài)類型變量的應(yīng)用inttest1(intn){inti=5;i+=n;returni;}inttest2(intn){staticinti=5;i+=n;returni;}intmain(void){for(inti=1;i<4;i++)printf("%5d",test1(5));printf("\n");for(inti=1;i<4;i++)printf("%5d",test2(5));printf("\n");return0;}程序5.12中,函數(shù)test1和函數(shù)test2的調(diào)用方法相同,傳給它們二者的實(shí)際參數(shù)也是相同的,唯一區(qū)別在于函數(shù)內(nèi)聲明的變量i的存儲(chǔ)類別不同。由表5.1的知識(shí)點(diǎn)可知:(1)函數(shù)test1被調(diào)用了3次,每次調(diào)用系統(tǒng)都要為它的形參n以及內(nèi)部聲明的自動(dòng)類型的局部變量i分配空間,且i被3次賦初值為5,3次調(diào)用傳遞給形參的值都是5,故3次調(diào)用的返回值也都是相同的,均為10;(2)函數(shù)test2同樣被調(diào)用了3次,每次調(diào)用系統(tǒng)都要為它的形參n分配空間,但由于局部變量i的存儲(chǔ)類別為靜態(tài),因此i的內(nèi)存空間只被分配一次,初值賦值為5也只執(zhí)行了1次,后續(xù)2次調(diào)用函數(shù)test2,語(yǔ)句staticinti=5;可理解為被忽略了,執(zhí)行語(yǔ)句i+=n;本質(zhì)是在i已有的數(shù)值的基礎(chǔ)上累計(jì)變化,故分別得到的返回值就是“101520”。下列程序的輸出結(jié)果是(

)。intfun3(intx){staticinta=3;a+=x;return(a);}intmain(void){intk=2,m=1,n;n=fun3(k);n=fun3(m);printf("%d\n",n);return0;}3469ABCD提交單選題10分外部(extern)變量某種意義上講就是全局變量。全局變量是從變量作用域的角度提出的;外部變量是從變量的存儲(chǔ)方式提出的,表示它的生存周期。因此,外部變量的定義就是全局變量的定義。若全局變量的定義在后,而使用在前;或者引用其他文件中的某些全局變量,這時(shí)都必須用extern對(duì)該變量進(jìn)行外部說明?!纠?.13】外部(extern)變量的使用intmax1(intx,inty);intmax2();intmain(void){externinta,b;printf("maxvalue=%d\n",max1(a,b));printf("maxvalue=%d\n",max2(a,b));return0;}intmax1(intx,inty){intz;z=x>y?x:y;returnz;}externinta,b;intmax2(){intz;z=a>b?a:b;returnz;}inta=20,b=40;程序5.13最后1行聲明了2個(gè)全局變量a和b,因此它們2者的作用范圍就是從聲明位置開始直到整個(gè)源程序文件的結(jié)尾,如果在它們的聲明位置之前使用這2個(gè)變量a和b,編譯器會(huì)報(bào)“使用了未聲明的標(biāo)識(shí)符”的錯(cuò)誤。解決上述編譯錯(cuò)誤的辦法是——使用extern關(guān)鍵字?jǐn)U展全局變量的已有適用范圍到一個(gè)更大的適用范圍,具體來說就是在需要擴(kuò)展的新位置處增加語(yǔ)句:externinta,b;注意上面這條語(yǔ)句:第一,只是擴(kuò)展了一個(gè)全局變量的適用范圍,并沒有增加新的全局變量,因此此時(shí)不能再給全局變量a和b賦予新的初值;第二,不能擴(kuò)展局部變量的適用范圍;第三,可以擴(kuò)展到該全局變量之前的某個(gè)函數(shù)中,例如程序5.13中,擴(kuò)展到前面main函數(shù)中;第四,可以擴(kuò)展到一個(gè)更大的全局適用范圍。寄存器(register)變量是指存放在寄存器中的變量。變量的值一般是存放在內(nèi)存中的,某些要頻繁使用的變量(例如循環(huán)計(jì)數(shù)變量),為了提高變量的存取效率,可將這些變量存放在寄存器(寄存器中的變量CPU運(yùn)算器可直接取用)中,將變量存儲(chǔ)類型定義為register型,定義形式為:

“register<數(shù)據(jù)類型><變量名表>;”。使用寄存器變量需要注意:第一,計(jì)算機(jī)中寄存器數(shù)量是有限的,因此不能有太多的寄存器變量;第二,只有局部自動(dòng)變量和形式參數(shù)可以定義為寄存器變量,全局變量和靜態(tài)變量不能定義為寄存器變量;第三,寄儲(chǔ)器變量沒有存儲(chǔ)器地址;第四,現(xiàn)在的編譯技術(shù)已十分先進(jìn),哪些變量保存在寄存器中能更好的體現(xiàn)程序的運(yùn)行性能,都是通過編譯器自動(dòng)判斷并進(jìn)行最優(yōu)化處理的;即使經(jīng)過編譯器的最優(yōu)化處理,這些保存在寄存器中的變量在程序?qū)嶋H執(zhí)行時(shí)也可能發(fā)生存儲(chǔ)位置的變更。因此,使用register進(jìn)行變量聲明也漸漸變得沒有意義了。例如:registerdoublemx;scanf(“%lf”,&mx);//*寄儲(chǔ)器變量mx不能使用取地址("&")運(yùn)算符*/在一個(gè)源文件中定義的全局變量,其作用域?yàn)椋?/p>

)。本文件的全部范圍本程序的全部范圍本函數(shù)的全部范圍從定義該變量的位置開始至本文件結(jié)束ABCD提交單選題10分討論:全局變量比局部變量自由度大,更方便?是否AB提交投票最多可選1項(xiàng)以下關(guān)于局部變量和全局變量的敘述錯(cuò)誤的是(

)。main函數(shù)中定義的變量是局部變量。局部變量可以與全局變量重名。形式參數(shù)不是局部變量。在所有函數(shù)外定義的變量是全局變量。ABCD提交單選題10分以下敘述中不正確的是(

)在不同的函數(shù)中可以使用相同名字的變量函數(shù)中的形式參數(shù)是局部變量在一個(gè)函數(shù)內(nèi)定義的變量只在本函數(shù)范圍內(nèi)有效在一個(gè)函數(shù)內(nèi)的復(fù)合語(yǔ)句中定義的變量在本函數(shù)范圍內(nèi)有效ABCD提交單選題10分綜合應(yīng)用實(shí)例5.45.4綜合應(yīng)用實(shí)例——使用格雷戈里公式求圓周率輸入精度值p,使用格雷戈里公式求圓周率常數(shù)的近似值,當(dāng)求和序列中的最后一項(xiàng)的絕對(duì)值小于精度值p時(shí)求和結(jié)束。要求定義和調(diào)用函數(shù)計(jì)算完成圓周率常數(shù)近似值的求解。運(yùn)用循環(huán)的有關(guān)知識(shí)可以編寫出如下程序。5.4綜合應(yīng)用實(shí)例根據(jù)題目要求:要定義和調(diào)用函數(shù)來計(jì)算圓周率常數(shù),且序列求和的過程中通項(xiàng)的精度值是可變的因此設(shè)計(jì)的函數(shù)有1個(gè)參數(shù)用于接收實(shí)際調(diào)用該函數(shù)時(shí)傳遞進(jìn)來的精度值,函數(shù)調(diào)用結(jié)束后的返回值即是最后的圓周率常數(shù)值。封裝函數(shù)的過程主要完成了2件工作:第一,從main函數(shù)的變量聲明開始直到倒數(shù)第3行抽取出來作為函數(shù)pi的函數(shù)體,再把其中聲明精度值的變量提出來作為函數(shù)的形參;第二,增加語(yǔ)句returnpi;返回最終計(jì)算得到的圓周率常數(shù)值。程序5.14B封裝函數(shù)使用格雷戈里公式計(jì)算圓周率常數(shù)值

doublepi(doublep)//形式參數(shù)p存放序列求和過程中的精度值{

doublepi=0.0;//存放圓周率常數(shù)值

doubleitem;//存放求和序列中的通項(xiàng)值

unsignedn=1;//序列求和中的項(xiàng)次序值

intflag=1;//序列求和中通項(xiàng)前的正負(fù)號(hào)標(biāo)志

item=1.0/(2*n-1);while(item>=p){pi+=flag*item;flag=-flag;n+=1;item=1.0/(2*n-1);}pi*=4;

returnpi;}printf("Valueofpiis%.8lf\n",pi(p1));printf("Valueofpiis%.8lf\n",pi(p2));return0;}程序5.15B運(yùn)行結(jié)果Valueofpiis3.14159065Valueofpiis3.14159263分析以上的運(yùn)行結(jié)果可知:調(diào)用封裝好的函數(shù)pi,該函數(shù)有唯一的形式參數(shù)用于接收實(shí)際的精度值,精度越高(相應(yīng)的精度數(shù)值就越?。﹦t計(jì)算的結(jié)果就越精確,函數(shù)的返回值就是在某個(gè)特定精度值下的圓周率常數(shù)值。intmain(void){doublep1=1e-6;doublep2=1e-8;printf("Valueofpiis%.8lf\n",pi(p1));printf("Valueofpiis%.8lf\n",pi(p2));return0;}分析以上的運(yùn)行結(jié)果可知:(1)調(diào)用封裝好的函數(shù)pi,該函數(shù)有唯一的形式參數(shù)用于接收實(shí)際的精度值,精度越高(相應(yīng)的精度數(shù)值就越小)則計(jì)算的結(jié)果就越精確;(2)函數(shù)的返回值就是在某個(gè)特定精度值下的圓周率常數(shù)值。5.4綜合應(yīng)用實(shí)例——求100到1000之間的全部素?cái)?shù)設(shè)計(jì)和利用函數(shù)求100到1000之間的全部素?cái)?shù),每輸出8個(gè)素?cái)?shù)換1行,每個(gè)素?cái)?shù)占6個(gè)字符寬度的位置。設(shè)計(jì)函數(shù)isPrime(intn)用于判斷傳入的整數(shù)是否為素?cái)?shù)。——從素?cái)?shù)定義出發(fā)完成的函數(shù)體intisPrime(intn){ intm;//函數(shù)內(nèi)部聲明的變量

for(m=2;m<n;m++) { if(n%m==0) return0;//返回值為0表數(shù)n不是素?cái)?shù)

}

return1;//返回值為1表數(shù)n是素?cái)?shù)}5.4綜合應(yīng)用實(shí)例intisPrime(intn);/*這行是函數(shù)isPrime的原型或聲明*/intmain(void){ inti; intc=0;//計(jì)數(shù)器,每產(chǎn)生1個(gè)素?cái)?shù)該變量的值就增加1

for(i=100;i<=1000;i++) { if(isPrime(i)==1) { c++; printf("%-6d",i); if(c%8==0)//如果計(jì)數(shù)達(dá)到了8的整數(shù)倍,則換行

printf("\n"); } } return0;}【例5.12】靜態(tài)類型變量的使用

注意,要調(diào)用優(yōu)化后的新函數(shù)須在源程序前添加語(yǔ)句#include<math.h>,因?yàn)樾潞瘮?shù)中用到了sqrt這個(gè)庫(kù)函數(shù)。intisPrime(intn){ intm;//函數(shù)內(nèi)部聲明的變量

intgate=(int)sqrt((double)n); for(m=2;m<=gate;m++) { if(n%m==0) return0;//返回值為0表數(shù)n不是素?cái)?shù)

}

return1;//返回值為1表數(shù)n是素?cái)?shù)}程序5.15運(yùn)行結(jié)果要調(diào)用數(shù)學(xué)處理函數(shù)時(shí),在#include命令行中應(yīng)包含(

)。"stdio.h""string.h""math.h""ctype.h"ABCD提交單選題10分工程案例分析5.55工程案例分析——5ms時(shí)間調(diào)度機(jī)【案例1】動(dòng)力系統(tǒng)控制中,程序設(shè)計(jì)常常是按照時(shí)間間隔來調(diào)用的,所以在程序運(yùn)行的最外層,會(huì)設(shè)計(jì)很多鬧鐘,例如1ms,5ms,直到1s以上的,不同的子功能模塊根據(jù)實(shí)際情況放入對(duì)應(yīng)的鬧鐘之下進(jìn)行調(diào)用。基于時(shí)間的調(diào)度在控制上經(jīng)常使用,程序按一個(gè)固定周期執(zhí)行數(shù)據(jù)更新對(duì)于PID等功能來說是很重要的。voidEvent_5MS(void){

a_hld_task_input_5msec();//調(diào)用下一個(gè)函數(shù)

bcs2_fast_input_driver();

trnsys_mgr_level05();

hp_egr_id();5工程案例分析——5ms時(shí)間調(diào)度機(jī)

endsv_main_fg();

etppc_main_fg();

trbwc_main_fg();

a_hld_task_output_5msec();}voida_hld_task_input_5msec(void){

/*CKCP*/

crankcase_pressure_input_driver_fg();//調(diào)用下一個(gè)函數(shù)5.5工程案例分析——5ms時(shí)間調(diào)度機(jī)

/*PFP*/

particulate_filter_pressure_input_driver();

/*TCWGP*/

tcwgp_input_driver();

/*TP*/

tp_input_driver_itppc();

return;}5工程案例分析——5ms時(shí)間調(diào)度機(jī)voidcrankcase_pressure_input_driver_fg(void){

if(ckcpm_fg_on!=FALSE)

{

crankcase_pressure_input_driver(&ahld_p_raw_cds_ckcp_fg,&ckcp_raw_fg);

}

return;}5工程案例分析——駕駛扭矩計(jì)算【案例2】以下是一個(gè)發(fā)動(dòng)機(jī)內(nèi)部調(diào)用各種函數(shù)來對(duì)加速過程進(jìn)行控制的部分程序,其中tqdrv_16ms_exec是每16ms執(zhí)行一次的函數(shù),而tqdrv_tipin被其調(diào)用,而tqdrv_tipin又調(diào)用了tqdrv_tipin_inhibit_calc。因?yàn)閠qdrv_tipin_inhibit不僅僅被tqdrv_16ms_exec調(diào)用,在ABS或者其他相關(guān)狀態(tài)變化時(shí)也會(huì)被調(diào)用,所以tqdrv_tipin_inhibit_calc不能直接寫在tqdrv_16ms_exec之中,而是單獨(dú)寫成一個(gè)函數(shù),在被需求的時(shí)候被調(diào)用。5工程案例分析——駕駛扭矩計(jì)算voidtqdrv_16ms_exec(void)/*駕駛扭矩16ms計(jì)算函數(shù)*/{

{

tqdv_delta_time=DeltaTimeSec(&tqdv_last_time);/*計(jì)算實(shí)際執(zhí)行間隔,以計(jì)算變化率等*/

tqdrv_oscmod();/*震動(dòng)監(jiān)控函數(shù)*/

tqdrv_dfso();/*減速斷油函數(shù)*/

tqdrv_tipout();/*減速相關(guān)計(jì)算函數(shù)*/

tqdrv_tipin();/*加速相關(guān)計(jì)算函數(shù)*/

}}5工程案例分析——駕駛扭矩計(jì)算voidtqdrv_tipin(void)/*加速相關(guān)計(jì)算函數(shù)*/{tqdrv_tipin_inhibit_calc();/*是否禁止加速相關(guān)的參數(shù)更新*/tqdrv_tipin_exit_calc();/*退出加速計(jì)算的函數(shù)*/tqdrv_tipin_ratio_calc_bg();/*目標(biāo)和實(shí)際加速度相關(guān)計(jì)算函數(shù)*/}5工程案例分析——駕駛扭矩計(jì)算voidtqdrv_tipin_inhibit_calc(void)/*是否禁止加速相關(guān)的參數(shù)更新*/{{

if((mfmflg!=FALSE)/*系統(tǒng)存在故障*/

||((TQ_TIP_NEUT!=FALSE)/*動(dòng)力系統(tǒng)沒有激活*/

&&(trload!=0)/*發(fā)動(dòng)機(jī)負(fù)荷不為0*/

&&(ndsflg==FALSE))/*變速箱在空檔*/

||((engine_speed>=TQ_TIP_NMAX)/*發(fā)動(dòng)機(jī)轉(zhuǎn)速在監(jiān)控的最高值之上*/

||(engine_speed<=TQ_TIP_NMIN))/*發(fā)動(dòng)機(jī)轉(zhuǎn)速在監(jiān)控的最低值之下*/

||(tr_lim_toil<1.0F)/*變速箱超溫狀態(tài)中*/5工程案例分析——駕駛扭矩計(jì)算

||(cool_flg!=FALSE)/*發(fā)動(dòng)機(jī)超溫狀態(tài)中*/

||(discutout!=0)/*減速斷油功能在禁止使用中*/

||(vspd<TQ_TIP_VS__A)/*車速小于允許加速計(jì)算的最低車速*/

||(ect<TQ_TIP_ECT__A)/*發(fā)動(dòng)機(jī)溫度小于允許加速計(jì)算的最低溫度*/

||(trac_active!=FALSE)/*ABS正在工作*/

||(tip_fuel_off!=FALSE))/*供油系統(tǒng)被禁止*/

{

tip_inhibit=TRUE;/*禁止加速相關(guān)的參數(shù)更新*/5工程案例分析——駕駛扭矩計(jì)算 } else {

tip_inhibit=FALSE;/*允許加速相關(guān)的參數(shù)更新*/

}}}小結(jié)5.65.6小結(jié)函數(shù)是C程序的最小單元;C程序是由一個(gè)主函數(shù)以及若干個(gè)函數(shù)構(gòu)成;主函數(shù)可以調(diào)用其它函數(shù),其它函數(shù)可以相互調(diào)用;必須有且只能有一個(gè)名為main的主函數(shù);C程序的執(zhí)行總是從main函數(shù)開始,在main中結(jié)束。注意區(qū)別函數(shù)的聲明、定義和調(diào)用。調(diào)用函數(shù)時(shí)實(shí)參的個(gè)數(shù)必須和形參保持一致,實(shí)參的類型必須向形參保持一致(至少是賦值兼容的);函數(shù)調(diào)用時(shí)參數(shù)傳值的規(guī)則可簡(jiǎn)單地概括為“由實(shí)參到形參的單向的值傳遞”,因?yàn)閷?shí)參和形參各有自己獨(dú)立的內(nèi)存空間。遞歸的本質(zhì),遞歸的調(diào)用過程,遞歸函數(shù)的編寫5.6小結(jié)變量根據(jù)其適用范圍可分為局部變量和全局變量,要正確區(qū)分它們,尤其注意局部變量3種構(gòu)成形態(tài)及其生存期問題。程序設(shè)計(jì)中應(yīng)盡量少的使用全局變量,因?yàn)椋喝肿兞吭诔绦蛉繄?zhí)行過程中都會(huì)占用存儲(chǔ)單元,降低了函數(shù)的通用性、可靠性和可移植性,降低程序清晰性,容易出錯(cuò)。以下對(duì)C語(yǔ)言函數(shù)的描述中,正確的是()。C程序由一個(gè)或一個(gè)以上的函數(shù)組成函數(shù)既可以嵌套定義又可以遞歸調(diào)用函數(shù)必須有返回值,否則不能使用函數(shù)C程序中調(diào)用關(guān)系的所有函數(shù)必須放在同一個(gè)程序文件中ABCD提交單選題10分謝謝第6章

數(shù)組C程序設(shè)計(jì)及工程案例分析XX大學(xué):XX學(xué)習(xí)目標(biāo)理解并能正確選擇數(shù)組數(shù)據(jù)結(jié)構(gòu)會(huì)熟練定義數(shù)組,初始化數(shù)組以及引用數(shù)組中的單個(gè)元素會(huì)使用數(shù)組對(duì)一組值進(jìn)行存儲(chǔ)、排序和查找會(huì)運(yùn)用數(shù)組作為參數(shù)傳遞會(huì)熟練定義和使用多維數(shù)組了解字符數(shù)組與字符串的關(guān)系,熟悉字符串的基本操作C語(yǔ)言里,一維數(shù)組元素的下標(biāo)是從0開始的。TFAB提交單選題10分目錄6.1一維數(shù)組6.2二維數(shù)組6.3字符串6.4綜合應(yīng)用實(shí)例---篩法求素?cái)?shù)6.5工程案例分析---利用數(shù)組存儲(chǔ)傳感器特性數(shù)據(jù)一維數(shù)組6.16.1.1一維數(shù)組的定義、引用和初始化C語(yǔ)言給我們提供了數(shù)組這種數(shù)據(jù)結(jié)構(gòu),幫助我們完成同時(shí)定義多個(gè)同類型變量的工作。定義數(shù)組的語(yǔ)法:數(shù)組元素類型數(shù)組名[數(shù)組元素個(gè)數(shù)];例如:inta[100];//定義含100個(gè)整型元素的數(shù)組adoubleb[30];//定義含30個(gè)雙精度型元素的數(shù)組bcharc[256]; //定義含256個(gè)字符型元素的數(shù)組c數(shù)組數(shù)組是一組位置相鄰的內(nèi)存單元,它們都具有相同的名稱和類型。要引用數(shù)組中的特定位置的元素,需要指定數(shù)組的名稱和數(shù)組中特定元素的位置編號(hào)(下標(biāo))。數(shù)組一組相關(guān)的內(nèi)存位置具有相同的名稱和類型對(duì)數(shù)組元素的使用必須指明:數(shù)組名位置編號(hào)語(yǔ)法:數(shù)組名[位置編號(hào)]數(shù)組第一個(gè)元素編號(hào)為0數(shù)組中的n個(gè)元素名為:c[0],c[1]...c[n–1]Nameofarray(Notethatallelementsofthisarrayhavethesamename,c)Positionnumberoftheelementwithinarraycc[6]-4560721543-89062-31645378c[0]c[1]c[2]c[3]c[11]c[10]c[9]c[8]c[7]c[5]c[4]假定double類型變量在內(nèi)存中占用8個(gè)字節(jié),且數(shù)組定義如下,則數(shù)組a在內(nèi)存中所占字節(jié)數(shù)是(

)。doublea[10];8801040ABCD提交單選題10分?jǐn)?shù)組元素的使用數(shù)組元素的使用和普通變量一樣c[3]=125c[5]=c[1]+c[2]c[8]=c[4]*c[7]數(shù)組下標(biāo)可以是一個(gè)表達(dá)式c[5–2]=100數(shù)組下標(biāo)可以是一個(gè)變量或表達(dá)式intx=1;c[x]=100;intx=7,y=3;c[y–x]=100;數(shù)組使用示例:

定義一個(gè)數(shù)組并使用循環(huán)來給數(shù)組中的元素賦值。#include<stdio.h>intmain(void){inta[5];for(inti=0;i<5;i++){a[i]=i*10;}for(inti=0;i<5;i++){printf("%d\t",a[i]);}return0;}注意

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論