C語言之函數

在C語言中,大多數功能都是靠函數來實現的,定義一個函數的具體格式以下:
返回值類型 函數名([[參數類型 參數名1], [參數類型 參數名2],..., [參數類型  參數n]])
{
       執行語句
       .........
       return 返回值;
}
釋義:
       返回值類型:用於限定函數返回值的數據類型;
       函數名:表示函數的名稱,該名稱能夠根據標識符命名規範來定義;
       參數類型:用於限定調用方法時傳入參數的數據類型;
       參數名:用於接收調用方法時傳入的數據;
       return關鍵字:用於結束函數,並返回函數指定類型的值;
       返回值:被return語句返回的值,該值返回給調用者。若是函數沒有返回值,則返回值類型要聲明爲void,此時,函數體中的return 語句能夠省略不寫。
       在以上語法中,函數中的「[[參數類型 參數名1],[參數類型 參數名2],...[參數類型 參數n]]」被稱做參數列表,它用於標水函數在調用時須要接收的參數。若是函數不須要接收任何參數,則參數列表爲空,這樣的函數被稱爲無參函數。若是參數列表不爲空的函數就是有參函數。以下兩種函數:
        無參函數: 在C語言中,無參函數的定義很簡單,定義以下:
        void func()
        {
              printf("hello word");
        }
        上述代碼中,func()函數就是一無參函數,在定義時參數列表爲空,要想執行這個函數須要在main()函數中調用它。以下程序員

#include <stdio.h>

//定義函數
void func()
{
    printf("hello word!\n");
}

int main(int argc, const char * argv[]) {

    
    func();  //打印hello word
    
   return 0;
}

運行結果:
hello word!
Program ended with exit code: 0

    有參函數
    與無參函數函數相比,有你參函數函數須要在定義時,在函數名稱後面的括號中填寫參數。所謂的參數是一個變量,用於接收調用函數傳入的數據。
    void func(int x, int y)
    {
         int sum = x + y;
         printf("sum = %d\n", sum);編程


    }
    以上代碼是兩個整數之和,以下:數組

#include <stdio.h>

//定義函數
void func(int x, int y)
{
    int sum = x + y;
    printf("sum = %d\n", sum);
}

int main(int argc, const char * argv[]) {

    
   func(3, 5);  //打印hello word
    
   return 0;
}
運行結果以下:
sum = 8
Program ended with exit code: 0

       函數的返回值數據結構

       函數的返回值是指函數被調用以後,返回給調用者的值,函數返回值的具體語法格式上以下:
       return 表達式;
       對於返回值爲空的函數,能夠直接在return語句後面加分號,具體語法格式以下:
       return;
       有返回值的函數以下示例:
       函數

#include <stdio.h>

//定義函數
int func(int x, int y)
{
    int sum = x + y;
    return sum;
}

int main(int argc, const char * argv[]) {

    
   int sum = func(3, 5);  //打印hello word
    printf("sum =%d\n", sum);
    
   return 0;
}
運行結果
sum =8
Program ended with exit code: 0

printf()函數和scanf()函數

       在C語言中,常常會進行一些輸入輸出操做,爲此,C語言提供了printf()和scanf()函數,其中,printf()函數用於控制檯輸出字符,scanf()函數用於讀取用戶的輸入。spa

       printf()函數
       在前面章節中,常用printf()函數輸出數據,它能夠經過格式控制字符輸出多個任意類型的數據。以下:
 code

經常使用格式字符 含義
%s 輸出一個字符串
%c 輸出一個字符
%d 以十進制輸出一個有符號整型
%u 以十進制輸出一個無符號整型
%o 以八進制輸出一個整數
%x 以十六進制輸出一個小寫整數
%X 以十六進制輸出一個大寫整數
%f 以十進制輸出一個浮點數
%e 以科學計數法輸出一個小寫浮點數
%E 以科學計數法輸出一個大寫浮點數

      scanf()函數
      scanf()函數負責從控制檯上接收用戶的輸入,它能夠靈活接收各類類型的數據,如字符串、字符、整型、浮點數等,scanf()函數也能夠經過格式控制字符控制用戶的輸入,其用法和printf()函數同樣。以下示例:遞歸

#include <stdio.h>
int main(int argc, const char * argv[]) {
    //輸入一個字符串, 用字符數組保存字符串
    char string[256];
    scanf("%s", string);
    printf("%s\n", string);
    
   return 0;
}
運行結果
dqk
dqk
Program ended with exit code: 0

以上代碼運行後輸入dqk並按回車鍵 而後控制檯會打印出結果:dqk.
注意:C語言中的終止符
      在使用scanf()函數獲取用戶輸入信息時,若是輸入的信息包含某個終止符,scanf()函數就會認爲輸入結束。以下一些常見的終止符:ci

字符 含義
0x20 空格
\t 水平製表符(tab鍵)
\n 換行
\v 垂直
\f 換頁
\r 回車

函數的調用方式

       函數是c語言的基本組成元素,要想實現函數的功能,必須學會正確調用函數。在c語言中,調用函數的具體語法格式以下:
       函數名([[實參列表1], [實參列表2]......])
       從上面的語法格式能夠看出,當調用一個函數時,須要明確函數名和實參列表。實參列表中的參數能夠是常量、變量、表達式或者空,各參數之間使用英文逗號分隔。
      根據函數在程序中出現的位置,能夠有下列三種函數調用方式:
      1.將函數做爲表達式調用
      將函數做爲表達式調用時,函數的返回值參與表達式的運算,此時要求函數必須有返回值。示例代碼以下:作用域

int sum = func(100, 4);

      2.將函數做爲語句調用
      函數以語句的形式出現時,能夠將函數做爲一條語句進行調用。示例代碼以下:

printf("哈哈哈 今天是週五");

     3.將函數做爲實參調用
     將函數做爲另外一個函數的實參,要求該函數有返回值,示例代碼以下:

printf("%d\n", func(100, 5));

      嵌套調用
      在c語言中函數的定義是獨立的,即一個函數不能定義在另一個函數內部。但在調用函數時,能夠在一個函數中調用另外一個函數,這就是函數的嵌套調用。示例代碼以下:

#include <stdio.h>

//求兩個數的和
int func1(int x, int y)
{
    return x + y;
}

//求兩個數之差
int func2(int x, int y)
{
    //調用函數1先求兩個數之和
    int sum = func1(x, y);
    return sum - y;
}

int main(int argc, const char * argv[]) {
    //輸入一個字符串, 用字符數組保存字符串
  
    int s = func2(10, 5);
    
    printf("%d\n", s);
    
   return 0;
}
運行結果:
10
Program ended with exit code: 0

腦洞大開:函數調用時最多能夠嵌套多少層?
      有沒有這個疑問:「既然函數嵌套調用和普通的調用看上去沒有什麼區別,那是否是能夠無限層的函數嵌套呢?」很遺憾,函數能夠嵌套調用多少層是由程序運行時一個名爲「棧」的數據結構決定的。通常而言,Windows上程序的默認棧大小大約爲8KB,每一次函數調用至少佔用8個字節,所以粗略計算下,函數調用只能只能嵌套大約一千層,若是嵌套調用的函數裏包含許多變量和參數,實際值要遠遠小於這個數目。
      固然,單純手動書寫代碼寫出一千層嵌套函數調用基本是不可能的,可是一種名爲「遞歸的方法能夠輕鬆達到這個上限。
遞歸調用
       所謂的遞歸就是函數內部調用自身的過程。須要注意的是,遞歸必需要求有結束條件,否則就會陷入無限遞歸的狀態,永遠沒法結束調用。接下來經過一個求1~100天然數之間的和來做爲一個案例,示例代碼以下:

#include <stdio.h>

int getsum(int n)
{
    if (n == 1) {
        return 1;
    }
    int temp = getsum(n-1);
    
    return temp + n;
}

int main(int argc, const char * argv[]) {

   //打印天然數之和
   printf("%d\n", getsum(100));
    
   return 0;
}
運行結果
5050
Program ended with exit code: 0

外部函數與內部函數

      前面關於函數的調用都是針對同一個源文件中其它函數進行調用的,在有些狀況下,函數也可能對另一個源文件中函數進行調用。當一個程序由多個源文件組成時,根據函數時可否被其它源文件調用,將函數分爲內部函數和外部函數。

       外部函數
       開發大型項目時,爲了便於團隊的協同工做;,須要把一個項目拆分紅不少源文件來分別實現,最終再把它們整合在一塊兒。爲了減小重複代碼,一個源文件有時須要調用其餘源文件中定義的函數。在c語言中,能夠被其它源文件調用的函數稱爲外部函數,在調用外部函數以前,須要在當前源文件中定義外部函數。定義外部函數的方式是在函數的返回值類型前面添加extern關鍵字,示例代碼以下:

extern int sum(int x, int y);

      在上述示例代碼中,編譯會經過extern關鍵字知道sum()函數時是定義在其餘文件中的外部函數。請看代碼:
      peresion.c 源文件:

#include "persion.h"

int sum(int x, int y){
    int sum = x + y;
    
    return sum;
}

     main.c 主函數文件:

extern int sum(int x, int y);

int main(int argc, const char * argv[]) {

    int y = sum(100, 10);

    printf("%d\n", y);
   return 0;
}

     運行結果:

110
Program ended with exit code: 0

爲簡化編程,C語言中容許在定義外部函數時省略關鍵字extern。在以上例子中外部函數sum()也能夠修改成下面的代碼:

int sum(int x, int y);

       上述代碼由函數的返回類型、函數名和參數列表組成,這類格式的代碼被稱爲函數原型。當代碼中包含函數原型時,可能會有下列兩種狀況:
       1.程序員但願編譯器自動從其餘文件中查找該函數的定義。

       2.程序員先定義未實現的空函數,而後在其餘文件中具體實現

      內部函數

      相對外部函數,外部函數只要聲明一個函數原型就可以調用其餘源文件中的函數。可是當多人蔘與開發一個項目時,頗有可能會出現函數重名的狀況,這樣,不一樣源文件中重名的函數就會互相干擾。此時,就須要一些特殊函數,這些函數只在它定義文件中有效,該類函數稱爲內部函數。
      在定義內部函數時,須要在函數的返回值類型前面添加static關鍵字(又稱爲靜態函數),示例代碼以下:

static void eat(int x)
{
    printf("%d", x);
}

請看以下案例:
       persion.c源文件:

#include "persion.h"

void eat(int x){
    
    x += x;
    
    printf("小狗吃了%d個饅頭", x);
}

       main.c 主函數源文件:

#include <stdio.h>

static void eat(int x)
{
    printf("小豬吃了%d個饅頭\n", x);
}

int main(int argc, const char * argv[]) {

    eat(10);
    
    return 0;
}

運行結果:

小豬吃了10個饅頭
Program ended with exit code: 0

以上代碼中在persion.c文件和main.c源文件中都定義了eat()函數,從運行結果中能夠看出打印的是main.c文件中的eat()函數,所以說明內部函數只會被自身調用,不會受到其餘文件中同名函數的影響。

局部變量與全局變量

      變量既能夠定義在函數內,也能夠定義在函數外。定義在不一樣位置的變量,其做用域也是不一樣的。C語言中的變量,按做用域範圍可分爲局部變量和全局變量。
      局部變量
      局部變量就是在函數內部聲明的變量,它只在本函數內有效,也就是說,只能在本函數內使用它。此外,局部變量只有當它所在的函數被調用時纔會被使用,而當函數調用結束時局部變量就會失去做用。

      全局變量       在全部函數外部定義的變量稱爲全局變量(包含main()函數),它不屬於哪個函數,而是屬於源程序。所以全局變量能夠爲程序中全部函數共用。它的有效範圍從定義開始到源程序結束。

相關文章
相關標籤/搜索