當前位置:才華齋>計算機>C語言>

C語言函式是什麼

C語言 閱讀(2.68W)

C程式的全部工作都是由各式各樣的函式完成的, 所以也把C語言稱為函式式語言。下面本站小編帶大家一起來看看詳細內容,希望對大家有所幫助!想了解更多相關資訊請持續關注我們應屆畢業生考試網!

C語言函式是什麼

由於採用了函式模組式的結構, C語言易於實現結構化程式設計。使程式的層次結構清晰,便於程式的編寫、閱讀、除錯。

在C語言中可從不同的角度對函式分類。

  1. 從函式定義的角度看,函式可分為庫函式和使用者定義函式兩種。

(1)庫函式

由C系統提供,使用者無須定義, 也不必在程式中作型別說明,只需在程式前包含有該函式原型的標頭檔案即可在程式中直接呼叫。在前面各章的例題中反覆用到printf 、 scanf 、 getchar 、putchar、gets、puts、strcat等函式均屬此類。

(2)使用者定義函式

由使用者按需要寫的函式。對於使用者自定義函式, 不僅要在程式中定義函式本身, 而且在主調函式模組中還必須對該被調函式進行型別說明,然後才能使用。

  2. C語言的函式兼有其它語言中的函式和過程兩種功能,從這個角度看,又可把函式分為有返回值函式和無返回值函式兩種。

(1)有返回值函式

此類函式被呼叫執行完後將向呼叫者返回一個執行結果, 稱為函式返回值。如數學函式即屬於此類函式。 由使用者定義的這種要返回函式值的函式,必須在函式定義和函式說明中明確返回值的型別。

(2)無返回值函式

此類函式用於完成某項特定的處理任務, 執行完成後不向呼叫者返回函式值。這類函式類似於其它語言的過程。 由於函式無須返回值,使用者在定義此類函式時可指定它的返回為“空型別”, 空型別的說明符為“void”。

  3. 從主調函式和被調函式之間資料傳送的角度看又可分為無參函式和有參函式兩種。

(1)無參函式

函式定義、函式說明及函式呼叫中均不帶引數。 主調函式和被調函式之間不進行引數傳送。 此類函式通常用來完成一組指定的功能,可以返回或不返回函式值。

(2)有參函式

也稱為帶參函式。在函式定義及函式說明時都有引數, 稱為形式引數(簡稱為形參)。在函式呼叫時也必須給出引數, 稱為實際引數(簡稱為實參)。 進行函式呼叫時,主調函式將把實參的值傳送給形參,供被調函式使用。

  4. C語言提供了極為豐富的庫函式, 這些庫函式又可從功能角度作以下分類。

(1)字元型別分類函式

用於對字元按ASCII碼分類:字母,數字,控制字元,分隔符,大小寫字母等。

(2)轉換函式

用於字元或字串的轉換;在字元量和各類數字量 (整型, 實型等)之間進行轉換;在大、小寫之間進行轉換。

(3)目錄路徑函式

用於檔案目錄和路徑操作。

(4)診斷函式

用於內部錯誤檢測

(5)圖形函式

用於螢幕管理和各種圖形功能。

(6)輸入輸出函式

用於完成輸入輸出功能。

(7)介面函式

用於與DOS,BIOS和硬體的介面。

(8)字串函式

用於字串操作和處理。

(9)記憶體管理函式

用於記憶體管理。

(10)數學函式

用於數學函式計算。

(11)日期和時間函式

用於日期,時間轉換操作。

(12)程序控制函式

用於程序管理和控制。

(13)其它函式

用於其它各種功能。

以上各類函式不僅數量多,而且有的還需要硬體知識才會使用,因此要想全部掌握則需要一個較長的學習過程。 應首先掌握一些最基本、 最常用的函式,再逐步深入。由於篇幅關係,本書只介紹了很少一部分庫函式, 其餘部分讀者可根據需要查閱有關手冊。

還應該指出的是,在C語言中,所有的函式定義,包括主函式main在內,都是平行的。也就是說,在一個函式的函式體內, 不能再定義另一個函式, 即不能巢狀定義。但是函式之間允許相互呼叫,也允許巢狀呼叫。習慣上把呼叫者稱為主調函式。 函式還可以自己呼叫自己,稱為遞迴呼叫。main 函式是主函式,它可以呼叫其它函式,而不允許被其它函式呼叫。 因此,C程式的執行總是從main函式開始, 完成對其它函式的呼叫後再返回到main函式,最後由main函式結束整個程式。一個C源程式必須有,也只能有一個主函式main。

  函式定義的一般形式

1.無參函式的一般形式

型別說明符 函式名()

{

型別說明

語句

}

其中型別說明符和函式名稱為函式頭。 型別說明符指明瞭本函式的型別,函式的型別實際上是函式返回值的型別。 該型別說明符與第二章介紹的各種說明符相同。 函式名是由使用者定義的識別符號,函式名後有一個空括號,其中無引數,但括號不可少。{} 中的內容稱為函式體。在函式體中也有型別說明, 這是對函式體內部所用到的變數的型別說明。在很多情況下都不要求無參函式有返回值, 此時函式型別符可以寫為void。

我們可以改為一個函式定義:

void Hello()

{

printf ("Hello,world");

}

這裡,只把main改為Hello作為函式名,其餘不變。Hello 函式是一個無參函式,當被其它函式呼叫時,輸出Hello world字串。

2.有參函式的一般形式

型別說明符 函式名(形式引數表)

型式引數型別說明

{

型別說明

語句

}

有參函式比無參函式多了兩個內容,其一是形式引數表, 其二是形式引數型別說明。在形參表中給出的引數稱為形式引數, 它們可以是各種型別的變數, 各引數之間用逗號間隔。在進行函式呼叫時,主調函式將賦予這些形式引數實際的值。 形參既然是變數,當然必須給以型別說明。例如,定義一個函式, 用於求兩個數中的大數,可寫為:

int max(a,b)

int a,b;

{

if (a>b) return a;

else return b;

}

第一行說明max函式是一個整型函式,其返回的函式值是一個整數。形參為a,b。第二行說明a,b均為整型量。 a,b 的具體值是由主調函式在呼叫時傳送過來的。在{}中的函式體內, 除形參外沒有使用其它變數,因此只有語句而沒有變數型別說明。 上邊這種定義方法稱為“傳統格式”。 這種格式不易於編譯系統檢查,從而會引起一些非常細微而且難於跟蹤的錯誤。ANSI C 的新標準中把對形參的型別說明合併到形參表中,稱為“現代格式”。

例如max函式用現代格式可定義為:

int max(int a,int b)

{

if(a>b) return a;

else return b;

}

現代格式在函式定義和函式說明(後面將要介紹)時, 給出了形式引數及其型別,在編譯時易於對它們進行查錯, 從而保證了函式說明和定義的一致性。例1.3即採用了這種現代格式。 在max函式體中的return語句是把a(或b)的值作為函式的值返回給主調函式。有返回值函式中至少應有一個return語句。 在C程式中,一個函式的定義可以放在任意位置, 既可放在主函式main之前,也可放在main之後。例如例1.3中定義了一個max 函式,其位置在main之後, 也可以把它放在main之前。

修改後的程式如下所示。

int max(int a,int b)

{

if(a>b)return a;

else return b;

}

void main()

{

int max(int a,int b);

int x,y,z;

printf("input two numbers:");

scanf("%d%d",&x,&y);

z=max(x,y);

printf("maxmum=%d",z);

}

現在我們可以從函式定義、 函式說明及函式呼叫的角度來分析整個程式,從中進一步瞭解函式的各種特點。程式的第1行至第5行為max函式定義。進入主函式後,因為準備呼叫max函式,故先對max函式進行說明(程式第8行)。函式定義和函式說明並不是一回事,在後面還要專門討論。 可以看出函式說明與函式定義中的函式頭部分相同,但是末尾要加分號。程式第12 行為呼叫max函式,並把x,y中的值傳送給max的形參a,b。max函式執行的

結果 (a或b)將返回給變數z。最後由主函式輸出z的值。

函式呼叫的一般形式前面已經說過,在程式中是通過對函式的呼叫來執行函式體的,其過程與其它語言的子程式呼叫相似。C語言中, 函式呼叫的一般形式為:

函式名(實際引數表) 對無參函式呼叫時則無實際引數表。 實際引數表中的引數可以是常數,變數或其它構造型別資料及表示式。 各實參之間用逗號分隔。'Next of Page在C語言中,可以用以下幾種方式呼叫函式:

1.函式表示式

函式作表示式中的一項出現在表示式中,以函式返回值參與表示式的運算。這種方式要求函式是有返回值的。例如: z=max(x,y)是一個賦值表示式,把max的返回值賦予變數z。'Next of Page

2.函式語句

函式呼叫的一般形式加上分號即構成函式語句。例如: printf ("%D",a);scanf ("%d",&b);都是以函式語句的方式呼叫函式。

3.函式實參

函式作為另一個函式呼叫的實際引數出現。 這種情況是把該函式的返回值作為實參進行傳送,因此要求該函式必須是有返回值的。例如: printf("%d",max(x,y)); 即是把max呼叫的返回值又作為printf函式的實參來使用的。在函式呼叫中還應該注意的一個問題是求值順序的問題。 所謂求值順序是指對實參表中各量是自左至右使用呢,還是自右至左使用。 對此, 各系統的規定不一定相同。在3.1.3節介紹printf 函式時已提

到過,這裡從函式呼叫的角度再強調一下。 看例5.2程式。

void main()

{

int i=8;

printf("%d%d%d%d",++i,--i,i++,i--);

}

如按照從右至左的順序求值。例5.2的執行結果應為:

8

7

7

8

如對printf語句中的++i,--i,i++,i--從左至右求值,結果應為:

9

8

8

9

應特別注意的是,無論是從左至右求值, 還是自右至左求值,其輸出順序都是不變的, 即輸出順序總是和實參表中實參的順序相同。由於Turbo C現定是自右至左求值,所以結果為8,7,7,8。上述問題如還不理解,上機一試就明白了。函式的引數和函式的值

  一、函式的引數

前面已經介紹過,函式的引數分為形參和實參兩種。 在本小節中,進一步介紹形參、實參的特點和兩者的關係。 形參出現在函式定義中,在整個函式體內都可以使用, 離開該函式則不能使用。實參出現在主調函式中,進入被調函式後,實參變數也不能使用。 形參和實參的功能是作資料傳送。發生函式呼叫時, 主調函式把實參的值傳送給被調函式的形參從而實現主調函式向被調函式的資料傳送。

函式的形參和實參具有以下特點:

1.形參變數只有在被呼叫時才分配記憶體單元,在呼叫結束時, 即刻釋放所分配的記憶體單元。因此,形參只有在函式內部有效。 函式呼叫結束返回主調函式後則不能再使用該形參變數。

2.實參可以是常量、變數、表示式、函式等, 無論實參是何種型別的量,在進行函式呼叫時,它們都必須具有確定的值, 以便把這些值傳送給形參。 因此應預先用賦值,輸入等辦法使實參獲得確定值。

3.實參和形參在數量上,型別上,順序上應嚴格一致, 否則會發生“型別不匹配”的錯誤。

4.函式呼叫中發生的資料傳送是單向的。 即只能把實參的值傳送給形參,而不能把形參的值反向地傳送給實參。 因此在函式呼叫過程中,形參的值發生改變,而實參中的值不會變化。例5.3可以說明這個問題。

void main()

{

int n;

printf("input number");

scanf("%d",&n);

s(n);

printf("n=%d",n);

}

int s(int n)

{

int i;

for(i=n-1;i>=1;i--)

n=n+i;

printf("n=%d",n);

}

本程式中定義了一個函式s,該函式的功能是求∑ni=1i 的值。在主函式中輸入n值,並作為實參,在呼叫時傳送給s 函式的形參量n( 注意,本例的形參變數和實參變數的識別符號都為n, 但這是兩個不同的量,各自的作用域不同)。 在主函式中用printf 語句輸出一次n值,這個n值是實參n的值。在函式s中也用printf 語句輸出了一次n值,這個n值是形參最後取得的n值0。從執行情況看,輸入n值為100。即實參n的值為100。把此值傳給函式s時,形參 n 的初值也為100,在執行函式過程中,形參n的值變為5050。 返回主函式之後,輸出實參n的值仍為100。可見實參的值不隨形參的變化而變化。

  二、函式的值

函式的值是指函式被呼叫之後, 執行函式體中的程式段所取得的並返回給主調函式的值。如呼叫正弦函式取得正弦值,呼叫例5.1的max函式取得的最大數等。對函式的值(或稱函式返回值)有以下一些說明:

1. 函式的值只能通過return語句返回主調函式。return 語句的一般形式為:

return 表示式;

或者為:

return (表示式);

該語句的功能是計算表示式的值,並返回給主調函式。 在函式中允許有多個return語句,但每次呼叫只能有一個return 語句被執行, 因此只能返回一個函式值。

2. 函式值的型別和函式定義中函式的型別應保持一致。 如果兩者不一致,則以函式型別為準,自動進行型別轉換。 3. 如函式值為整型,在函式定義時可以省去型別說明。

4. 不返回函式值的函式,可以明確定義為“空型別”, 型別說明符為“void”。如例5.3中函式s並不向主函式返函式值,因此可定義為:

void s(int n)

{ ……

}

一旦函式被定義為空型別後, 就不能在主調函式中使用被調函式的函式值了。例如,在定義s為空型別後,在主函式中寫下述語句 sum=s(n); 就是錯誤的。為了使程式有良好的可讀性並減少出錯, 凡不要求返回值的函式都應定義為空型別。函式說明在主調函式中呼叫某函式之前應對該被調函式進行說明, 這與使用變數之前要先進行變數說明是一樣的。 在主調函式中對被調函式作說明的目的是使編譯系統知道被調函式返回值的型別, 以便在主調函式中按此種類型對返回值作相應的處理。 對被調函式的說明也有兩種格式,一種為傳統格式,其一般格式為: 型別說明符 被調函式名(); 這種格式只給出函式返回值的型別,被調函式名及一個空括號。

這種格式由於在括號中沒有任何引數資訊, 因此不便於編譯系統進行錯誤檢查,易於發生錯誤。另一種為現代格式,其一般形式為:

型別說明符 被調函式名(型別 形參,型別 形參…);

或為:

型別說明符 被調函式名(型別,型別…);

現代格式的括號內給出了形參的型別和形參名, 或只給出形參型別。這便於編譯系統進行檢錯,以防止可能出現的錯誤。例5.1 main函式中對max函式的說明若

用傳統格式可寫為:

int max();

用現代格式可寫為:

int max(int a,int b);

或寫為:

int max(int,int);

C語言中又規定在以下幾種情況時可以省去主調函式中對被調函式的函式說明。

1. 如果被調函式的返回值是整型或字元型時, 可以不對被調函式作說明,而直接呼叫。這時系統將自動對被調函式返回值按整型處理。例5.3的主函式中未對函式s作說明而直接呼叫即屬此種情形。

2. 當被調函式的函式定義出現在主調函式之前時, 在主調函式中也可以不對被調函式再作說明而直接呼叫。例如例5.1中, 函式max的定義放在main 函式之前,因此可在main函式中省去對 max函式的函式說明int max(int a,int b)。

3. 如在所有函式定義之前, 在函式外預先說明了各個函式的型別,則在以後的各主調函式中,可不再對被調函式作說明。例如:

char str(int a);

float f(float b);

main()

{

……

}

char str(int a)

{

……

}

float f(float b)

{

……

}

其中第一,二行對str函式和f函式預先作了說明。 因此在以後各函式中無須對str和f函式再作說明就可直接呼叫。

4. 對庫函式的呼叫不需要再作說明, 但必須把該函式的標頭檔案用include命令包含在原始檔前部。陣列作為函式引數陣列可以作為函式的引數使用,進行資料傳送。 陣列用作函式引數有兩種形式,一種是把陣列元素(下標變數)作為實參使用; 另一種是把陣列名作為函式的形參和實參使用。

  一、陣列元素作函式實參

陣列元素就是下標變數,它與普通變數並無區別。 因此它作為函式實參使用與普通變數是完全相同的,在發生函式呼叫時, 把作為實參的陣列元素的值傳送給形參,實現單向的值傳送。例5.4說明了這種情況。

[例5.4]判別一個整數陣列中各元素的值,若大於0 則輸出該值,若小於等於0則輸出0值。程式設計如下:

void nzp(int v)

{

if(v>0)

printf("%d ",v);

else

printf("%d ",0);

}

main()

{

int a[5],i;

printf("input 5 numbers");

for(i=0;i<5;i++)

{

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

nzp(a[i]);

}

}void nzp(int v)

{ ……

}

main()

{

int a[5],i;

printf("input 5 numbers");

for(i=0;i<5;i++)

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

nzp(a[i]);

}

}

本程式中首先定義一個無返回值函式nzp,並說明其形參v 為整型變數。在函式體中根據v值輸出相應的結果。在main函式中用一個for 語句輸入陣列各元素, 每輸入一個就以該元素作實參呼叫一次nzp函式,即把a[i]的值傳送給形參v,供nzp函式使用。