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函數使用。
-
C++ cin輸入流詳解
標準輸入流是從標準輸入設備(鍵盤)流向程序的數據。在頭文件iostream.h中定義了cin、cout、cerr、clog4個流對象,cin是輸入流,cout、cerr、clog是輸出流。下面是小編為大家整理的C++cin輸入流詳解,歡迎參考~cin是istream類的對象,它從標準輸入設備(鍵盤)獲取數據,程...
-
c語言—文件的創建與建立
今天要介紹的是有關文件的創建與讀取的語法,事實上,c語言中對於這方面的`已經有相當經典且應用相當廣泛的語法了,但是我今天想講一講關於c++中的相關語法,以下僅供參考!以下是代碼:首先是文件的創建:#include#include#includeusingnamespacestd;intmain(){ofstreamout...
-
C語言的第一個程序
C語言是一門通用計算機編程語言,應用廣泛。C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、產生少量的機器碼以及不需要任何運行環境支持便能運行的`編程語言。下面小編帶大家看看第一個C語言程序。第一個C語言程序實例説明輸出"Hello,world!"是...
-
C語言數組的定義及引用
引導語:數組是在程序設計中,為了處理方便,把具有相同類型的若干變量按有序的形式組織起來的一種形式。以下是本站小編分享給大家的C語言數組,希望大家喜歡!1.1一維數組的定義、初始化和引用1.一維數組的定義方式為:類型説明符數組名[常量表達式](1)數組名的命名方法...