C語言入門第十四篇,函數

在一開始我們介紹C語言的時候我們介紹了程序是由一個主函數和若干子函數組成(見第一篇初識C語言)。函數英文是function,有方式、方法的意思。那麼我們在程序設計的時候就可以把程序寫成很多個程序塊(函數),每塊程序塊實現不同的功能。
我們來看看例子。

#include<stdio.h>

void print_helloworld()
{
    printf("hello world!\n");
}

int main()
{
    print_helloworld();
    return 0;
}

上面的代碼是一個簡單的函數,實現的功能是輸出hello world。函數名字叫print_helloworld,下面是具體的語法。
類型 函數名(形式參數)
{
代碼塊
}
上面的代碼沒有參數,所以形式參數(簡稱:形參)那裏是空着的。函數名類似變量的名字,是由自己決定,前面說了函數除了void類型以外其他的都必須有返回值,所以一定要確定好你函數的返回值的類型。

函數聲明

函數其實和前面的變量差不多都是需要先聲明才能使用的,我們說一個具體的例子來講函數的聲明,假設我要聲明一個比較兩個數大小的函數,首先我要傳入這兩個數a,b,也就說我要聲明兩個形式參數,接着我返回一個最大值來表明這兩個數中較大的(函數只能返回一個值),函數如果不是void(空)的類型的話,是必須要有返回值的。返回值的類型就是你定義函數的類型,用return來返回值。如下:

int compare(int a,int b)

函數的聲明可以放在主函數的前面和後面。上面的程序是放在前面的,下面我們來看看放在後面的。

#include<stdio.h>

void print_helloworld(); 

int main()
{
    print_helloworld();
    return 0;
}

void print_helloworld()
{
    printf("hello world!\n");
}

這裏我們對函數先進行了聲明,最後纔來實現了這個函數的功能。當然void print_helloworld(); 這個也可以放在main函數的裏面,在調用這個函數之前就好。

int main()
{
    void print_helloworld();
    print_helloworld();
    return 0;
}

這裏涉及到作用域的問題,後面會說。這裏只要記住函數要被使用就必須先有聲明(當然函數在調用之前聲明實現的話只需要把完整的函數寫出來就好了,例如我們這篇文章的第一個程序)。這裏不要忘了函數如果先聲明但是沒實現的話,後面要加分號。

函數參數
上面我們簡單的講函數聲明所以沒有加函數的參數,我們來看看下面這個程序。

#include<stdio.h>

int compare(int a,int b)
{
    if(a<b)
    return b;
    else
    return a;
}

int main()
{
    int m,n,c;
    scanf("%d%d",&m,&n);
    c=compare(m,n);
    printf("最大值爲:%d\n",c);
    return 0;
}

這個程序很簡單,輸入兩個數的,然後調用函數判斷較大的那個數是多少,並輸出最大值。

函數的參數,我們傳入什麼參數類型就必須聲明什麼類型的形式參數,不然編譯器會報錯。

C語言採用的是傳值調用,意味着他所有傳入的參數在函數裏面都是原來參數的複製(ps:記住這點很重要),我們在後面指針與函數中更加深刻的去討論這個問題。

返回值
返回值意味着函數的結束,函數一旦執行到return語句就會跳出函數塊。返回值要和函數聲明的類型一樣,否則可能會出錯。返回值可以由變量接收,或者直接輸出。上面的例子是由變量接收的。也可以直接輸出的。

int main()
{
    int m,n,c;
    scanf("%d%d",&m,&n);
    printf("最大值爲:%d\n",compare(m,n));
    return 0;
}

上面例子就是直接輸出返回值。

遞歸函數

遞歸函數就是函數自己調用自己,初學者都很不太喜歡遞歸,因爲他沒有循環那麼直觀。但是你會漸漸的發現,遞歸可以大大減少代碼量,並且將複雜問題簡單化,符合人類的邏輯思維。遞歸的思想在編程中非常重要。
我們印象中最熟悉的就是斐波那契數(不瞭解的可以去看一下百度百科 斐波那契數
F1=0
F2=1
Fn=Fn-1+Fn-2
這是典型的數學裏面的遞推式子。下面來看一下實現的代碼:

int Fib(int n)
{
    if(n==0)
    return 0;
    if(n==1)
    return 1;
    return Fib(n-1)+Fib(n-2);
}

這段程序的實現功能很簡單,函數接受一個輸入參數n,求出第n個斐波那契數。邏輯思路是函數不斷的調用自己,直到n==0和n==1時,返回0和1,然後一層一層的返回值。最後得到你的n的值。遞歸函數就是數據結構堆棧實現的,遞歸就是不斷壓棧,達到出棧條件的時候,進行出棧操作。如下圖:
出棧入棧

如圖所示,我們先將Fn放入下面接着放Fn-1一直這樣放下去,當n=0的時候開始出棧,F0和F1已知,就可以得到F2,遞推下去就會得到Fn。當然這個出棧和入棧的操作是編譯器進行的。如果你對堆棧這些都不太理解,就當是瞭解一下這些內容就好,後面會專門講遞歸函數。

總結
函數的大部分內容都簡單的介紹了一下,但是對於一些其他的問題還是需要再下一篇進行更深層次的討論。這篇希望大家熟悉函數的基本語法和應用。

練習
1.輸入一個n,求出前n項斐波那契數的和。
2.編寫一個求最大公約數和一個最小公倍數的函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章