1. 程式人生 > >8、C語言之函數

8、C語言之函數

開始 span 作用域 執行 系統 發的 改變 棧區 ror

一、函數淺析

1、函數

  函數是一個可以反復使用的程序段,從其它的程序段中均可以通過調用語句來使用這個程序段,完成既定的工作

  說明:

  (1)建立函數稱為“函數定義”,使用函數稱為“函數調用”

  (2)調用其它函數的函數稱為“主調函數”,而被調用的函數稱為“被調函數”

  一個實用的C語言源程序總是由許多函數組成,這些函數都是根據實際任務,由用戶自己來編寫,在這些函數中可以調用C提供的庫函數,也可以調用由用戶自己或他人編寫的函數。

  但是,一個C語言源程序無論包含了多少函數,在正常情況下總是從main函數開始執行,main函數結束

  C語言源程序可以分放在不同的文件中,所以一個源程序中的函數也可以分放在不同的文件中。

2、庫函數

  C語言提供了豐富的庫函數,包括常用的數學函數、字符和字符串處理函數,輸入輸出函數等等。

  調用C語言標準庫函數時要求的include命令行

  #include<stdio.h>

3、函數的定義

  定義格式:

    函數類型 函數名(形參類型說明表)

   {

      說明部分

      語句部分

    }

  (1)函數有“函數頭”和“函數體”兩部分組成;函數體由語句和其他分程序組成

  (2)函數類型規定了函數返回值的數據類型,若無返回值,則數據類型為void,如果函數有返回值,則在函數體中應有一條返回語句“return 表達式;”,無返回值,則返回語句應為“return;”也可以省略。

  (3)形式參數表時逗號分隔的若幹形式參數,每個形式參數可以時一個變量名、數組名、指針變量名和指針數組名,形參列表中每個參數的數據類型必須給出。

  (4)形式參數可以為空,但是圓括號不能省略

  (5)形參若是數組,只需給出數組名,[]中數組長度不許給出

  (6)函數體中不允許再嵌套定義函數,能嵌套調用

函數返回值

  函數的值通過return語句返回,return語句的形式如下:

    return 表達式; 或 return (表達式);

  說明:

    (1)return語句中的表達式的值就是所求的函數值,此表達式的值的類型必須與函數首部所說明的類型一致。若類型不一致,則以函數值的類型為主,由系統自動轉換。(可以寫個函數測試以下)

    (2)無論函數體中有多少個return語句,return語句只可能執行一次;

    (3)return語句中可以不含表達式,這時必須定義函數為void類型。

    (4)函數體內可以沒有return語句,只是也必須定義函數為void類型。

  

函數調用

  形式:函數名(實際參數表)

  (1)沒有返回值的函數調用格式:

    函數名(實際參數表);

  (2)有返回值的函數調用格式:

    x=函數名(實際參數表);

二、函數的深析

1、基本思想:

    將一個大程序按功能分割成一些小模塊

  特點:

    各個模塊相對獨立、功能單一、結構清晰、接口簡單

    控制了程序的復雜性

    提高原件的可靠性

    縮短開發周期

    避免程序開發的重復勞動

    易於維護和功能擴充

  開發方法

    自上向下,逐步分解,分而治之

  函數調用過程分析

    (1)為函數的所有形參分配內存單元

    (2)計算各個實參表達式的值,一一對應的賦值個相應的形參(若無形參,上述過程不執行)

    (3)進入函數體,執行函數中的語句,實現函數的功能

    (4)執行到return語句時,計算return語句中的表達式的值,(若無返回值函數,本項不做),返回到主調函數

    (5)釋放形參及本函數內的局部變量所占的內存,繼續執行主調函數中的後繼語句

2、函數間的傳值

C語言中,主調函數和被調函數之間的數據可以通過三種方式進行傳遞

  (1)值傳遞

    值傳遞是個單向傳遞過程,兩個單向傳遞構成雙向傳遞

    主調函數的內容傳遞給被調函數:

      實際參數賦值給形式參數

    (在C語言中,數據只能從實際參數單向傳遞給形參,俗稱“按值”傳遞,用戶不能再函數中改變對應實參的值)

    被調函數的內容傳給主調函數

      通過return語句把內容賦給主調函數

 1 #include<stdio.h>
 2 int fun(int x,int y)
 3 {
 4     if(x==y)
 5         return x;
 6     else
 7         return ((x+y)/2);
 8 }
 9 void main()
10 {
11     int a = 4,b=5,c=6;
12     printf("%d\n",fun(2*a,fun(b,c)));//值傳遞
13     return 0;
14 }

  (2)地址傳遞

    方式:函數調用時,將數據的存儲地址作為參數傳遞給形參,當然此時的形參只能時存儲地址的變量(指針變量)。才能達到“雙向”傳送的目的。

  數組名可作為函數參數。(實參和形參都應用數組名)

  (3)全局變量傳遞(這不是一種好的方式,通常不推薦使用)

3、函數的嵌套調用和遞歸調用

  (1)函數的嵌套調用

    函數甲調用了函數乙,而函數乙又調用了函數丙。C規定:函數定義不可嵌套,但可以嵌套調用函數。

  (2)函數的遞歸調用

    函數直接或間接的調用自身叫做函數的遞歸調用

    遞歸的特點:

      遞歸必須有遞歸結束條件;

      遞歸過程首先是一級一級遞推(即當前調用未結束又引出下一層調用),而滿足遞歸結束條件時結束遞推,再一級一級的回歸(即一級一級再返回上一級的調用繼續完成上一級的未完成的操作)。

    說明:

      C編譯系統對遞歸函數的自調用次數沒有限制,每調用函數一次,在內存堆棧區分配空間,用於存放函數變量、返回值等信息,所以遞歸次數過多,可能引起堆棧溢出。

 1 #include<stdio.h>
 2 int fac(int n)
 3 {
 4     int t;
 5     if(n == 1 || n ==0)//遞歸結束條件
 6         return 1;
 7     else
 8     {
 9         t = n*fac(n-1);//有規律地遞減
10         return t;//返回上一層調用
11     }
12 }
13 void main()
14 {
15     int m, y;
16     printf("Enter m:");
17     scanf("%d",&m);
18     if(m < 0)
19         printf("Input data error!\n");
20     else
21     {
22         y = fac(m);
23         printf("\n%d! = %d\n",m,y);
24     }
25     return 0;
26 }

補充知識:

  變量時對程序中數據的存儲空間的抽象

  (1)局部變量

    定義:在函數內定義,只在函數內有效

    使用:不同函數中同名變量占不同的存儲單元

    說明:形參屬於局部變量

  (2)全局變量

    定義:在函數外面定義的變量

    外部變量的作用域:對伊只有一個源程序文件構成的程序,外部變量的作用域時從定義它的位置開始,直至它所在源程序文件的結束

    特點:外部變量的使用增加了函數之間傳遞數據的途徑,在外部變量的作用域內的任何函數都能引用該外部變量,一個函數對外部變量的修改,能影響到其他引用這個變量的函數;因此對外部變量的使用不當,會產生意外的錯誤。

8、C語言之函數