程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言入門知識 >> C語言——函數

C語言——函數

編輯:C語言入門知識

C源程序是由函數組成。函數是C源程序的基本模塊,通過對函數模塊的調用實現特定的功能。C語言中的函數相當於其它高級語言的子程序。C語言不僅提供了極為豐富的庫函數(如Turbo C,MS C 都提供了三百多個庫函數),還允許用戶建立自己定義的函數。C語言稱為函數式語言。

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

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

(1)庫函數

(2)用戶定義函數:必須對該被調函數進行類型說明,然後才能使用。

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

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

(1)無參函數:可以返回或不返回函數值。

(2)有參函數

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

(1)字符類型分類函數

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

(2)轉換函數

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

(3)目錄路徑函數

用於文件目錄和路徑操作。

(4)診斷函數

用於內部錯誤檢測。

(5)圖形函數

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

(6)輸入輸出函數

用於完成輸入輸出功能。

(7)接口函數

用於與DOS,BIOS和硬件的接口。

(8)字符串函數

用於字符串操作和處理。

(9)內存管理函數

用於內存管理。

(10)數學函數

用於數學函數計算。

(11)日期和時間函數

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

(12)進程控制函數

用於進程管理和控制。

(13)其它函數

用於其它各種功能。

二、在一個函數的函數體內,不能再定義另一個函數,即不能嵌套定義。但是函數之間允許相互調用,也允許嵌套調用。習慣上把調用者稱為主調函數。函數還可以自己調用自己,稱為遞歸調用。main 函數是主函數,它可以調用其它函數,而不允許被其它函數調用。因此,C程序的執行總是從main函數開始,完成對其它函數的調用後再返回到main函數,最後由main函數結束整個程序。一個C源程序必須有,也只能有一個主函數main。函數的類型實際上是函數返回值的類型。有參函數比無參函數多了兩個內容,其一是形式參數表,其二是形式參數類型說明。在形參表中給出的參數稱為形式參數,它們可以是各種類型的變量,各參數之間用逗號間隔。函數定義、函數說明及函數調用函數說明與函數定義中的函數頭部分相同,但是末尾要加分號。

以下幾種方式調用函數:

1.函數表達式

2.函數語句

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

3.函數實參

應特別注意的是,無論是從左至右求值, 還是自右至左求值,其輸出順序都是不變的, 即輸出順序總是和實參表中實參的順序相同。函數的參數和函數的值發生函數調用時,主調函數把實參的值傳送給被調函數的形參從而實現主調函數向被調函數的數據傳送。

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

1.形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。2.實參可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須具有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使實參獲得確定值。

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

4.函數調用中發生的數據傳送是單向的。 即只能把實參的值傳送給形參,而不能把形參的值反向地傳送給實參。因此在函數調用過程中,形參的值發生改變,而實參中的值不會變化。

三、函數的值

函數的值是指函數被調用之後,執行函數體中的程序段所取得的並返回給主調函數的值。

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

在函數中允許有多個return語句,但每次調用只能有一個return 語句被執行,因此只能返回一個函數值。

2. 函數值的類型和函數定義中函數的類型應保持一致。 如果兩者不一致,則以函數類型為准,自動進行類型轉換。

3. 如函數值為整型,在函數定義時可以省去類型說明。

4. 不返回函數值的函數,可以明確定義為“空類型”, 類型說明符為“void”。

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

1. 如果被調函數的返回值是整型或字符型時,可以不對被調函數作說明,而直接調用。這2. 當被調函數的函數定義出現在主調函數之前時,在主調函數中也可以不對被調函數再作說明而直接調用。

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

4. 對庫函數的調用不需要再作說明, 但必須把該函數的頭文件用include命令包含在源文件前部。

五、數組名作為函數參數

用數組名作函數參數與用數組元素作實參有幾點不同:

1. 用數組元素作實參時,只要數組類型和函數的形參變量的類型一致,那麼作為下標變量的數組元素的類型也和函數形參變量的類型是一致的。對數組元素的處理是按普通變量對待的。

2. 在普通變量或下標變量作函數參數時,形參變量和實參變量是由編譯系統分配的兩個不同的內存單元。在函數調用時發生的值傳送是把實參變量的值賦予形參變量。實參數組的首地址賦予形參數組名。形參數組名取得該首地址之後,也就等於有了實在的數組。實際上是形參數組和實參數組為同一數組,共同擁有一段內存空間。

3. 前面已經討論過,在變量作函數參數時,所進行的值傳送是單向的。即只能從實參傳向形參,不能從形參傳回實參。形參的初值和實參相同,而形參的值發生改變後,實參並不變化,兩者的終值是不同的。例5.3證實了這個結論。而當用數組名作函數參數時,情況則不同。由於實際上形參和實參為同一數組,因此當形參數組發生變化時,實參數組也隨之變化。當然這種情況不能理解為發生了“雙向”的值傳遞。但從實際情況來看,調用函數之後實參數組的值將由於形參數組值的變化而變化。

從運行結果可以看出,數組b 的初值和終值是不同的,數組b 的終值和數組a是相同的。這說明實參形參為同一數組,它們的值同時得以改變。

用數組名作為函數參數時還應注意以下幾點:

a. 形參數組和實參數組的類型必須一致,否則將引起錯誤。

b. 形參數組和實參數組的長度可以不相同,因為在調用時,只傳送首地址而不檢查形參數組的長度。當形參數組的長度與實參數組不一致時,雖不至於出現語法錯誤(編譯能通過),但程序執行結果將與實際不符,這是應予以注意的。

函數的嵌套調用

六、C語言中不允許作嵌套的函數定義。因此各函數之間是平行的,不存在上一級函數和下一級函數的問題。但是C語言允許在一個函數的定義中出現對另一個函數的調用。這樣就出現了函數的嵌套調用。即在被調函數中又調用其它函數。

函數的遞歸調用

一個函數在它的函數體內調用它自身稱為遞歸調用。在遞歸調用中, 主調函數又是被調函數。形參變量只在被調用期間才分配內存單元,調用結束立即釋放。

七、C語言中的變量,按作用域范圍可分為兩種,即局部變量和全局變量。

(一)局部變量

局部變量也稱為內部變量。局部變量是在函數內作定義說明的。其作用域僅限於函數內,離開該函數後再使用這種變量是非法的。

關於局部變量的作用域還要說明以下幾點:

1. 主函數中定義的變量也只能在主函數中使用,不能在其它函數中使用。同時,主函數中也不能使用其它函數中定義的變量。因為主函數也是一個函數,它與其它函數是平行關系。這一點是與其它語言不同的,應予以注意。

2. 形參變量是屬於被調函數的局部變量,實參變量是屬於主調函數的局部變量。

3. 允許在不同的函數中使用相同的變量名,它們代表不同的對象,分配不同的單元,互不干擾,也不會發生混淆。

4. 在復合語句中也可定義變量,其作用域只在復合語句范圍內。

(二)全局變量

全局變量也稱為外部變量,它是在函數外部定義的變量。

只有在函數內經過說明的全局變量才能使用。全局變量的說明符為extern。但在一個函數之前定義的全局變量,在該函數內使用可不再加以說明。

對於全局變量還有以下幾點說明:

1. 對於局部變量的定義和說明,可以不加區分。外部變量定義必須在所有的函數之外,且只能定義一次。其一般形式為: [extern] 類型說明符變量名,變量名…其中方括號內的extern可以省去不寫。

2. 外部變量可加強函數模塊之間的數據聯系,但是又使函數要依賴這些變量,因而使得函數的獨立性降低。從模塊化程序設計的觀點來看這是不利的,因此在不必要時盡量不要使用全局變量。

3. 在同一源文件中,允許全局變量和局部變量同名。在局部變量的作用域內,全局變量不起作用。

變量的存儲類型各種變量的作用域不同,就其本質來說是因變量的存儲類型相同。所謂存儲類型是指變量占用內存空間的方式,也稱為存儲方式。

變量的存儲方式可分為“靜態存儲”和“動態存儲”兩種。

靜態存儲變量是一直存在的, 而動態存儲變量則時而存在時而消失。我們又把這種由於變量存儲方式不同而產生的特性稱變量的生存期。生存期表示了變量存在的時間。生存期和作用域是從時間和空間這兩個不同的角度來描述變量的特性,這兩者既有聯系,又有區別。一個變量究竟屬於哪一種存儲方式,並不能僅從其作用域來判斷,還應有明確的存儲類型說明。

八、 在C語言中,對變量的存儲類型說明有以下四種:

auto 自動變量

register 寄存器變量

extern 外部變量

static 靜態變量

自動變量和寄存器變量屬於動態存儲方式, 外部變量和靜態變量屬於靜態存儲方式。 因此變量說明的完整形式應為: 存儲類型說明符 數據類型說明符 變量名,變量名…; 例如:

static int a,b; 說明a,b為靜態類型變量

auto char c1,c2; 說明c1,c2為自動字符變量

static int a[5]={1,2,3,4,5}; 說明a為靜整型數組

extern int x,y; 說明x,y為外部整型變量

下面分別介紹以上四種存儲類型:

(一)自動變量的類型說明符為auto。

這種存儲類型是C語言程序中使用最廣泛的一種類型。C語言規定,函數內凡未加存儲類型說明的變量均視為自動變量,也就是說自動變量可省去說明符auto。

自動變量具有以下特點:

1. 自動變量的作用域僅限於定義該變量的個體內。

2. 自動變量屬於動態存儲方式,只有在使用它,即定義該變量的函數被調用時才給它分配存儲單元,開始它的生存期。函數調用結束,釋放存儲單元,結束生存期。

3. 由於自動變量的作用域和生存期都局限於定義它的個體內( 函數或復合語句內),因此不同的個體中允許使用同名的變量而不會混淆。即使在函數內定義的自動變量也可與該函數內部的復合語句中定義的自動變量同名。

4. 對構造類型的自動變量如數組等,不可作初始化賦值。

(二)外部變量外部變量的類型說明符為extern。

1. 外部變量和全局變量是對同一類變量的兩種不同角度的提法。全局變是是從它的作用域提出的,外部變量從它的存儲方式提出的,表示了它的生存期。

2. 當一個源程序由若干個源文件組成時, 在一個源文件中定義的外部變量在其它的源文件中也有效。

(三)靜態變量

靜態變量的類型說明符是static。 靜態變量當然是屬於靜態存儲方式,但是屬於靜態存儲方式的量不一定就是靜態變量,例如外部變量雖屬於靜態存儲方式,但不一定是靜態變量,必須由 static加以定義後才能成為靜態外部變量,或稱靜態全局變量。

1. 靜態局部變量

在局部變量的說明前再加上static說明符就構成靜態局部變量。

靜態局部變量屬於靜態存儲方式,它具有以下特點:

(1)靜態局部變量在函數內定義,但不象自動變量那樣,當調用時就存在,退出函數時就消失。靜態局部變量始終存在著,也就是說它的生存期為整個源程序。

(2)靜態局部變量的生存期雖然為整個源程序,但是其作用域仍與自動變量相同,即只能在定義該變量的函數內使用該變量。退出該函數後,盡管該變量還繼續存在,但不能使用它。

(3)允許對構造類靜態局部量賦初值(4)對基本類型的靜態局部變量若在說明時未賦以初值,則系統自動賦予0值。而對自動變量不賦初值,則其值是不定的。

2.靜態全局變量

全局變量(外部變量)的說明之前再冠以static就構成了靜態的全局變量。全局變量本身就是靜態存儲方式,靜態全局變量當然也是靜態存儲方式。這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態全局變量的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。而靜態全局變量則限制了其作用域,即只在定義該變量的源文件內有效,在同一源程序的其它源文件中不能使用它。由於靜態全局變量的作用域局限於一個源文件內,只能為該源文件內的函數公用,因此可以避免在其它源文件中引起錯誤。從以上分析可以看出,把局部變量改變為靜態變量後是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜態變量後是改變了它的作用域,限制了它的使用范圍。因此static 這個說明符在不同的地方所起的作用是不同的。應予以注意。

(四)C語言提供了另一種變量,即寄存器變量。這種變量存放在CPU的寄存器中,使用時,不需要訪問內存,而直接從寄存器中讀寫,這樣可提高效率。寄存器變量的說明符是register。對於循環次數較多的循環控制變量及循環體內反復使用的變量均可定義為寄存器變量。

對寄存器變量還要說明以下幾點:

1. 只有局部自動變量和形式參數才可以定義為寄存器變量。因為寄存器變量屬於動態存儲方式。凡需要采用靜態存儲方式的量不能定義為寄存器變量。

2. 在Turbo C,MS C等微機上使用的C語言中,實際上是把寄存器變量當成自動變量處理的。因此速度並不能提高。而在程序中允許使用寄存器變量只是為了與標准C保持一致。

3. 即使能真正使用寄存器變量的機器,由於CPU 中寄存器的個數是有限的,因此使用寄存器變量的個數也是有限的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved