函數(shù)分為庫函數(shù)和自定義函數(shù),在調(diào)用庫函數(shù)時只要標(biāo)明頭文件(所謂頭文件就是一個東西,里面包括了一些函數(shù)各聲明之類的,當(dāng)你要調(diào)用它中的函數(shù)時就就得先向程序說明你要調(diào)用這個文件里的函數(shù),否則有有侵權(quán)行為哦)可以在主調(diào)函數(shù)中調(diào)用這個頭文件里的所有函數(shù)了,例如頭文件為#includestdio.h你就可以在主調(diào)函數(shù)中調(diào)用這個頭文件里的函數(shù):
創(chuàng)新互聯(lián)自成立以來,一直致力于為企業(yè)提供從網(wǎng)站策劃、網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、做網(wǎng)站、電子商務(wù)、網(wǎng)站推廣、網(wǎng)站優(yōu)化到為企業(yè)提供個性化軟件開發(fā)等基于互聯(lián)網(wǎng)的全面整合營銷服務(wù)。公司擁有豐富的網(wǎng)站建設(shè)和互聯(lián)網(wǎng)應(yīng)用系統(tǒng)開發(fā)管理經(jīng)驗、成熟的應(yīng)用系統(tǒng)解決方案、優(yōu)秀的網(wǎng)站開發(fā)工程師團(tuán)隊及專業(yè)的網(wǎng)站設(shè)計師團(tuán)隊。
main
{ printf("haha");/*這時main函數(shù)為主調(diào)函數(shù),printf為被調(diào)函數(shù)*/
}
調(diào)用自定義函數(shù)時其實和調(diào)用庫函數(shù)一樣的,只不過這個函數(shù)是你自己定義的,再如:
main
{ void f();/*聲明 f()函數(shù)*/
f(); /*調(diào)用f()函數(shù)*/
}
f()
{
printf("haha");/*f()函數(shù)調(diào)用庫函數(shù)*/
}
工具/材料
Ubuntu16.04
gcc+vim
01
打開Ubuntu,并在目標(biāo)路徑下開啟一個終端。
02
選定一個路徑,使用touch命令創(chuàng)建三個文件,function.h,function.c,test.c,分別用來做函數(shù)頭文件、函數(shù)源文件以及測試文件
03
這里以四則運算函數(shù)為例說明函數(shù)的編寫流程與調(diào)用流程。首先用vim命令與vsplit依次打開三個文件。
04
在頭文件中添加重復(fù)包含的宏,并添加四則運算的函數(shù)聲明。
05
在function.c中將function.h包含進(jìn)來,并具體實現(xiàn)四個方法。注意出發(fā)要對除數(shù)是否為0進(jìn)行判斷。
06
然后編寫測試程序進(jìn)行測試??偟某绦虼a如下:
07
保存所有的程序并退出,使用gcc進(jìn)行編譯,并運行得到的結(jié)果如下。這就是函數(shù)的聲明、定義以及調(diào)用。
*********您好!Yadie.23很高興能為你解答。*********
+++++++++++++++++++++++++++++++++++++++++++++++++
#includestdio.h
void
fun(int
x)
{
if
(x100
||
x0)
printf("無效成績");
//條件加掛號
else
if
(x=90)
printf("優(yōu)");
else
if
(x=80)
printf("良");
else
if
(x=70)
printf("中");
else
if
(x=60)
printf("及格");
else
printf("不及格");
}
void
main()
{
int
a;
printf("請輸入學(xué)生成績:");
scanf("%d",a);
fun(a);
}
+++++++++++++++++++++++++++++++++++++++++++++++++
You
can
have
a
try,maybe
my
answer
useful
to
you.
如滿意,Yadie.23十分感謝您的采納。*^-^*
C語言中調(diào)用函數(shù)的方法及步驟:
工具/原料:C語言
1、首先需要輸入想要調(diào)用的函數(shù)。
2、然后當(dāng)輸入一個括號后,即可觀察他的參數(shù)。
3、接著在對應(yīng)的參數(shù)中輸入?yún)?shù)值。
4、然后,系統(tǒng)會發(fā)生一個警告。
5、接著需要調(diào)用它相應(yīng)的頭文件。
6、最后再次編譯,發(fā)現(xiàn)沒有任何警告和錯誤即可。
要了解調(diào)試程序的最好方法,首先要分析一下調(diào)試過程的三個要素:
應(yīng)該用什么工具調(diào)試一個程序?
用什么辦法才能找出程序中的錯誤?
怎樣才能從一開始就避免錯誤?
應(yīng)該用什么工具調(diào)試一個程序?
有經(jīng)驗的程序員會使用許多工具來幫助調(diào)試程序,包括一組調(diào)試程序和一些"lint”程序,當(dāng)然,編譯程序本身也是一種調(diào)試工具。
在檢查程序中的邏輯錯誤時,調(diào)試程序是特別有用的,因此許多程序員都把調(diào)試程序作為基本的調(diào)試工具。一般來說,調(diào)試程序能幫助程序員完成以下工作:
(1)觀察程序的運行情況
僅這項功能就使一個典型的調(diào)試程序具備了不可估量的價值。即使你花了幾個月的時間精心編寫了一個程序,你也不一定完全清楚這個程序每一步的運行情況。如果程序員忘記了某些if語句、函數(shù)調(diào)用或分支程序,可能會導(dǎo)致某些程序段被跳過或執(zhí)行,而這種結(jié)果并不是程序員所期望的。不管怎樣,在程序的執(zhí)行過程中,尤其是當(dāng)程序有異常表現(xiàn)時,如果程序員能隨時查看當(dāng)前被執(zhí)行的是那幾行代碼,那么他就能很好地了解程序正在做什么以及錯誤發(fā)生在什么地方。
(2)設(shè)置斷點
通過設(shè)置斷點可以使程序在執(zhí)行到某一點時暫時停住。當(dāng)你知道錯誤發(fā)生在程序的哪一部分時,這種方法是特別有用的。你可以把斷點設(shè)置在有問題的程序段的前面、中間或后面。當(dāng)程序執(zhí)行到斷點時,就會暫時停住,此時你可以檢查所有局部變量、參數(shù)和全局變量的值。如果一切正常,可以繼續(xù)執(zhí)行程序,直到遇到另一個斷點,或者直到引起問題的原因暴露出來。
(3)設(shè)置監(jiān)視
程序員可以通過調(diào)試程序監(jiān)視一個變量,即連續(xù)地監(jiān)視一個變量的值或內(nèi)容。如果你清楚一個變量的取值范圍或有效內(nèi)容,那么通過這種方法就能很快地找出錯誤的原因。此外,你可以讓調(diào)試程序替你監(jiān)視變量,并且在某個變量超出預(yù)先定義的取值范圍或某個條件滿足時使程序暫停執(zhí)行。如果你知道變量的所有行為,那么這么做是很方便的。
好的調(diào)試程序通常還提供一些其它功能來簡化調(diào)試工作。然而,調(diào)試程序并不是唯一的調(diào)試工具,lint程序和編譯程序本身也能提供很有價值的手段來分析程序的運行情況。
注意:lint程序能分辨數(shù)百種常見的編程錯誤,并且能報告這些錯誤發(fā)生在程序的哪一部分。盡管其中有一些并不是真正的錯誤,但大部分還是有價值的。
lint程序和編譯程序所提供的一種典型功能是編譯時檢查(compile—time checks),這種功能是調(diào)試程序所不具備的。當(dāng)用這些工具編譯你的程序時,它們會找出程序中有問題的程序段,可能產(chǎn)生意想不到的效果的程序段,以及常見的錯誤。下面將分析幾個這種檢查方式的應(yīng)用例子,相信對你會有所幫助。
等于運算符的誤用
編譯時檢查有助于發(fā)現(xiàn)等于運算符的誤用。請看下述程序段:
void foo(int a,int b)
{
if ( a = b )
{
/ * some code here * /
}
}
這種類型的錯誤一般很難發(fā)現(xiàn)!程序并沒有比較兩個變量,而是把b的值賦給了a,并且在b不為零的條件下執(zhí)行if體。一般來說,這并不是程序員所希望的(盡管有可能)。這樣一來,不僅有關(guān)的程序段將被執(zhí)行錯誤的次數(shù),并且在以后用到變量a時其值也是錯誤的。
未初始化的變量
編譯時檢查有助于發(fā)現(xiàn)未初始化的變量。請看下面的函數(shù):
void average ( float ar[], int size )
{
float total;
int a;
for( a = 0;asize; ++a)
{
total+=ar[a];
}
printf(" %f\n", total / (float) size );
}
這里的問題是變量total沒有被初始化,因此它很可能是一個隨機的無用的數(shù)。數(shù)組所有元素的值的和將與這個隨機數(shù)的值相加(這部分程序是正確的),然后輸出包括這個隨機數(shù)在內(nèi)的一組數(shù)的平均值。
變量的隱式類型轉(zhuǎn)換
在有些情況下,C語言會自動將一種類型的變量轉(zhuǎn)換為另一種類型。這可能是一件好事(程序員不用再做這項工作),但是也可能會產(chǎn)生意想不到的效果。把指針類型隱式轉(zhuǎn)換成整型恐怕是最糟糕的隱式類型轉(zhuǎn)換。
void sort( int ar[],int size )
{
/* code to sort goes here * /
}
int main()
{
int arrgy[10];
sort( 10, array );
}
上述程序顯然不是程序員所期望的,雖然它的實際運行結(jié)果難以預(yù)測,但無疑是災(zāi)難性的。
用什么辦法才能找出程序中的錯誤?
在調(diào)試程序的過程中,程序員應(yīng)該記住以下幾種技巧:
先調(diào)試程序中較小的組成部分,然后調(diào)試較大的組成部分
如果你的程序編寫得很好,那么它將包含一些較小的組成部分,最好先證實程序的這些部分是正確的。盡管程序中的錯誤并不一定發(fā)生在這些部分中,但是先調(diào)試它們有助于你理解程序的總體結(jié)構(gòu),并且證實程序的哪些部分不存在錯誤。進(jìn)一步地,當(dāng)你調(diào)試程序中較大的組成部分時,你就可以確信那些較小的組成部分是正常工作的。
徹底調(diào)試好程序的一個組成部分后,再調(diào)試下一個組成部分
這一點非常重要。如果證實了程序的一個組成部分是正確的,不僅能縮小可能存在錯誤的范圍,而且程序的其它組成部分就能安全地使用這部分程序了。這里應(yīng)用了一種很好的經(jīng)驗性原則,簡單地說就是調(diào)試一段代碼的難度與這段代碼長度的平方成正比,因此,調(diào)試一段20行的代碼比調(diào)試一段10行的代碼要難4倍。因此,在調(diào)試過程中每次只把精力集中在一小段代碼上是很有幫助的。當(dāng)然,這僅僅是一個總的原則,具體使用時還要視具體情況而定。
連續(xù)地觀察程序流(flow)和數(shù)據(jù)的變化
這一點也很重要!如果你小心仔細(xì)地設(shè)計和編寫程序,那么通過監(jiān)視程序的輸出你就能準(zhǔn)確地知道正在執(zhí)行的是哪部分代碼以及各個變量的內(nèi)容都是什么。當(dāng)然,如果程序表現(xiàn)不正常,你就無法做到這一點。為了做到這一點,通常只能借助于調(diào)試程序或者在程序中加入大量的print語句來觀察控制流和重要變量的內(nèi)容。
始終打開編譯程序警告選項 并試圖消除所有警告
在開發(fā)程序的過程中,你自始至終都要做到這一點,否則,你就會面臨一項十分繁重的工作。盡管許多程序員認(rèn)為消除編譯程序警告是一項繁瑣的工作,但它是很有價值的。編譯程序給出警告的大部分代碼至少都是有問題的,因此用一些時間把它們變成正確的代碼是值得的;而且,通過消除這些警告,你往往會找到程序中真正發(fā)生錯誤的地方。
準(zhǔn)確地縮小存在錯誤的范圍
如果你能一下子確定存在錯誤的那部分程序并在其中找到錯誤,那就會節(jié)省許多調(diào)試時間,并且你能成為一個收入相當(dāng)高的專業(yè)調(diào)試員。但事實上,我們并不能總是一下子就命中要害,因此,通常的做法是逐步縮小可能存在錯誤的程序范圍,并通過這種過程找出真正存在錯誤的那部分程序。不管錯誤是多么難于發(fā)現(xiàn),這種做法總是有效的。當(dāng)你找到這部分程序后,就可以把所有的調(diào)試工作集中到這部分程序上了。不言而喻,準(zhǔn)確地縮小范圍是很重要的,否則,最終集中精力調(diào)試的那部分程序很可能是完全正確的。
如何從一開始就避免錯誤?
有這樣一句諺語——“防患于未然”,它的意思是避免問題的出現(xiàn)比出現(xiàn)問題后再想辦法彌補要好得多。這在計算機編程中也是千真萬確的!在編寫程序時,一個經(jīng)驗豐富的程序員所花的時間和精力要比一個缺乏經(jīng)驗的程序員多得,但正是這種耐心和嚴(yán)謹(jǐn)?shù)木幊田L(fēng)格使經(jīng)驗豐富的程序員往往只需花很少的時間來調(diào)試程序,而且,如果此后程序要解決某個問題或做某種改動,他便能很快地修正錯誤并加入相應(yīng)的代碼。相反,對于一個粗制濫造的程序,即使它總的來說還算正確,那么改動它或者修正其中一個很快就暴露出來的錯誤,都會是一場惡夢。
一般來說,按結(jié)構(gòu)化程序設(shè)計原則編寫的程序是易于調(diào)試和修改的,下面將介紹其中的一些原則。
程序中應(yīng)有足夠的注釋
有些程序員認(rèn)為注釋程序是一項繁瑣的工作,但即使你從來沒想過讓別人來讀你的程序,你也應(yīng)該在程序中加入足夠的注釋,因為即使你現(xiàn)在認(rèn)為清楚明了的語句,在幾個月以后往往也會變得晦澀難懂。這并不是說注釋越多越好,過多的注釋有時反而會混淆代碼的原意。但是,在每個函數(shù)中以及在執(zhí)行重要功能或并非一目了然的代碼前加上幾行注釋是必要的。下面就是一段注釋得較好的代碼:
/*
* Compute an integer factorial value using recursion.
* Input an integer number.
* Output : another integer
* Side effects : may blow up stack if input value is * Huge *
*/
int factorial ( int number)
{
if ( number = 1)
return 1; /* The factorial of one is one; QED * /
else
return n * factorial( n - 1 );
/ * The magic! This is possible because the factorial of a
number is the number itself times the factorial of the
number minus one. Neat! * /
}
函數(shù)應(yīng)當(dāng)簡潔
按照前文中曾提到的這樣一條原則——調(diào)試一段代碼的難度和這段代碼長度的平方成正比——函數(shù)編寫得簡潔無疑是有益的。但是,需要補充的是,如果一個函數(shù)很簡潔,你就應(yīng)該多花一點時間去仔細(xì)地分析和檢查它,以確保它準(zhǔn)確無誤。此后你可以繼續(xù)編寫程序的其余部分,并且可以對剛才編寫的函數(shù)的正確性充滿信心,你再也不需要檢查它了。對于一段又長又復(fù)雜的例程,你往往是不會有這樣的信心的。
編寫短小簡潔的函數(shù)的另一個好處是,在編寫了一個短小的函數(shù)之后,在程序的其它部分就可以使用這個函數(shù)了。例如,如果你在編寫一個財務(wù)處理程序,那么你在程序的不同部分可能都需要按季、按月、按周或者按一月中的某一天等方式來計算利息。如果按非結(jié)構(gòu)化原則編寫程序,那么在計算利息的每一處都需要一段獨立的代碼,這些重復(fù)的代碼將使程序變得冗長而難讀。然而,你可以把這些任務(wù)的實現(xiàn)簡化為下面這樣的一個函數(shù):
/*
* ComDllte what the "real" rate of interest would be
* for a given flat interest rate, divided into N segments
*/
double Compute Interest( double Rate, int Segments )
{
int a;
double Result = 1.0;
Rate /= (double) Segments;
for( a = 0; a Segments ; ++a )
Result * =Rate;
return Result;
}
在編寫了上述函數(shù)之后,你就可以在計算利息的每一處調(diào)用這個函數(shù)了。這樣一來,你不僅能有效地消除每一段復(fù)制的代碼中的錯誤,而且大大縮短了程序的長度,簡化了程序的結(jié)構(gòu)。這種技術(shù)往往還會使程序中的其它錯誤更容易被發(fā)現(xiàn)。
當(dāng)你習(xí)慣了用這種方法把程序分解為可控制的模塊后,你就會發(fā)現(xiàn)它還有更多的妙用。
程序流應(yīng)該清晰,避免使用goto語句和其它跳轉(zhuǎn)語句
這條原則在計算機技術(shù)領(lǐng)域內(nèi)已被廣泛接受,但在某些圈子中對此還很有爭議。然而,人們也一致認(rèn)為那些通過少數(shù)語句使程序流無條件地跳過部分代碼的程序調(diào)試起來要容易得多,因為這樣的程序通常更加清晰易懂。許多程序員不知道如何用結(jié)構(gòu)化的程序結(jié)構(gòu)來代替那些“非結(jié)構(gòu)化的跳轉(zhuǎn)”,下面的一些例子說明了應(yīng)該如何完成這項工作:
for( a = 0; a100s ++a)
{
Func1( a );
if (a = = 2 ) continue;
Func2( a );
}
當(dāng)a等于2時,這段程序就通過continue語句跳過循環(huán)中的某余部分。它可以被改寫成如下的形式:
for( a = 0; a100; ++a)
{
Func1 (a);
if (a !=2 )
Func2(a) ;
}
這段程序更易于調(diào)試,因為花括號內(nèi)的代碼清楚地顯示了應(yīng)該執(zhí)行和不應(yīng)該執(zhí)行什么。那么,它是怎樣使你的代碼更易于修改和調(diào)試的呢?假設(shè)現(xiàn)在要加入一些在每次循環(huán)的最后都要被執(zhí)行的代碼,在第一個例子中,如果你注意到了continue語句,你就不得不對這段程序做復(fù)雜的修改(不妨試一下,因為這并非是顯而易見的!);如果你沒有注意到continue語句,那么你恐怕就要犯一個難以發(fā)現(xiàn)的錯誤了。在第二個例子中,要做的修改很簡單,你只需把新的代碼加到循環(huán)體的末尾。
當(dāng)你使用break語句時,可能會發(fā)生另外一種錯誤。假設(shè)你編寫了下面這樣一段程序:
for (a =0) a100; ++a)
{
if (Func1 (a) ==2 )
break;
Func2 (a) ;
}
假設(shè)函數(shù)Funcl()的返回值永遠(yuǎn)不會等于2,上述循環(huán)就會從1進(jìn)行到100;反之,循環(huán)在到達(dá)100以前就會結(jié)束。如果你要在循環(huán)體中加入代碼,看到這樣的循環(huán)體,你很可能就會認(rèn)為它確實能從0循環(huán)到99,而這種假設(shè)很可能會使你犯一個危險的錯誤。另一種危險可能來自對a值的使用,因為當(dāng)循環(huán)結(jié)束后,a的值并不一定就是100。
c語言能幫助你解決這樣的問題,你可以按如下形式編寫這個for循環(huán):
for(a=O;a100Func1(a)!=2;++a)
上述循環(huán)清楚地告訴程序員:“從0循環(huán)到99,但一旦Func1()等于2就停止循環(huán)”。因為整個退出條件非常清楚,所以程序員此后就很難犯前面提到的那些錯誤了。
函數(shù)名和變量名應(yīng)具有描述性
使用具有描述性的函數(shù)和變量名能更清楚地表達(dá)代碼的意思——并且在某種程度上這本身就是一種注釋。以下幾個例子就是最好的說明:
y=p+i-c;
和
YearlySum=Principal+Interest-Charges:
哪一個更清楚呢?
p=*(l+o);
和
page=List[offset];
哪一個更清楚呢?
C語言中,函數(shù)調(diào)用的一般形式為:
函數(shù)名(實際參數(shù)表)
對無參函數(shù)調(diào)用時則無實際參數(shù)表。實際參數(shù)表中的參數(shù)可以是常數(shù)、變量或其它構(gòu)造類型數(shù)據(jù)及表達(dá)式。各實參之間用逗號分隔。
#includestdio.h
int?fun(int?x,?int?y);?//?函數(shù)聲明,如果函數(shù)寫在被調(diào)用處之前,可以不用聲明
void?main()
{
int?a=1,?b=2,?c;
c?=?fun(a,?b);?//?函數(shù)的調(diào)用,調(diào)用自定義函數(shù)fun,其中a,b為實際參數(shù),傳遞給被調(diào)用函數(shù)的輸入值
}
//?自定義函數(shù)fun
int?fun(int?x,?int?y)??//?函數(shù)首部
{??//?{}中的語言為函數(shù)體
return?xy???x?:?y;??//?返回x和y中較大的一個數(shù)
}
擴(kuò)展資料
C語言中不允許作嵌套的函數(shù)定義。因此各函數(shù)之間是平行的,不存在上一級函數(shù)和下一級函數(shù)的問題。但是C語言允許在一個函數(shù)的定義中出現(xiàn)對另一個函數(shù)的調(diào)用。
這樣就出現(xiàn)了函數(shù)的嵌套調(diào)用。即在被調(diào)函數(shù)中又調(diào)用其它函數(shù)。這與其它語言的子程序嵌套的情形是類似的。其關(guān)系可表示如圖。
圖表示了兩層嵌套的情形。其執(zhí)行過程是:執(zhí)行main函數(shù)中調(diào)用a函數(shù)的語句時,即轉(zhuǎn)去執(zhí)行a函數(shù),在a函數(shù)中調(diào)用b 函數(shù)時,又轉(zhuǎn)去執(zhí)行b函數(shù),b函數(shù)執(zhí)行完畢返回a函數(shù)的斷點繼續(xù)執(zhí)行,a函數(shù)執(zhí)行完畢返回main函數(shù)的斷點繼續(xù)執(zhí)行。
參考資料:函數(shù)調(diào)用_百度百科