C語言基礎-第五課-函數
1 函數
1.1 函數的原型和調用
在使用函數前必須定義或者聲明函數
double circle(double r); int main() { double length = circle(10); printf("length = %f\n", length); return 0; }
double circle(double r) { return 2 * 3.14 * r; } |
1.2 函數的形參與實參
在調用函數的時候,函數大多數都有參數,主調函數和被調用函數之間需要傳遞數據。
在定義函數時函數名後面括弧中的變量名稱為“形式參數”,簡稱形參。在調用函數時,函數名後面括號中的變量或表達式稱為“實際參數”,簡稱實參。
1形參在未出現函數調用時,他們並不占用內存單元,只有在發生函數調用的時候形參才被分配內存,函數調用完成後,形參所占的內存被釋放
2實參可以是變量,常量或者表達式
3在定義函數時,一定要指定形參的數據類型
4形參與實參的數據類型一定要可兼容
5在C語言中,實參與形參的數據傳遞是“值傳遞”,即單向傳遞,只由實參傳遞給形參,而不能由形參傳遞給實參。
如果函數的參數是個數組,那麽是可以通過形參修改實參的值的
1.3 函數的返回類型與返回值
1函數的返回值通過函數中的return獲得,如果函數的返回值為void可以不需要return語句。
2函數return語句中的返回值數據類型應該與函數定義時相同。
3如果函數中沒有return語句,那麽函數將返回一個不確定的值。
1.4 main函數與exit函數與函數的return語句
int test1() { printf("111111\n");
//return 0; exit(0);//在子函數中調用exit同樣代表程序終止,但在子函數中調用return只是子函數終止,程序正常執行
printf("222222\n"); }
int main() { test1(); printf("AAAAAA\n"); exit(100);//exit是C語言的庫函數,調用exit的結果就是程序終止 return 100;//在main函數中調用exit與調用return是一樣的 printf("CCCCCCC\n");
return 0;//main函數return代表程序終止 printf("BBBBBB\n"); } |
1.5 多個源代碼文件程序的編譯
1.5.1 頭文件的使用
如果把main函數放在第一個文件中,而把自定義函數放在第二個文件中,那麽就需要在第一個文件中聲明函數原型。
如果把函數原型包含在一個頭文件裏,那麽就不必每次使用函數的時候都聲明其原型了。把函數聲明放入頭文件是很好的習慣。
1.5.2 #include與#define的意義
#include就是簡單的文件內容替換
#define就是簡單的文本替換而已
1.5.3 #ifndef與#endif
#ifndef的意思就是條件預編譯,如果#ifndef 後面的條件成立,那麽就預編譯從#ifndef開始到#endif之間的代碼,否則不會去預編譯這段代碼
1.6 函數的遞歸
函數可以調用自己,這就叫函數的遞歸
void recurse(int i) { if (i > 0) { recurse(i - 1); } printf("i = %d\n", i); }
int main() { recurse(10); return 0; } |
1.6.1 遞歸的過程分析
void up_down(int n) { printf("in %d, location %p\n", n, &n); if (n < 4) up_down((n + 1)); printf("out %d, location %p\n", n, &n); }
int main() { up_down(1); return 0; } |
有n個人排成一隊,問第n個人多少歲,他回答比前面一個人大2歲,再問前面一個人多少歲,他回答比前面一個人大2歲,一直問到最後問第一個人,他回答10歲
int age(int n) { int i; if (n == 1) i = 10; else i = age(n - 1) + 2; return i; } |
將10進制數轉化為二進制數的例子
234在十進制下為2 * 10的2次方 + 3 * 10的1次方 + 4*10的0次方。
奇數的二進制最後一位一定是1,偶數的二進制最後一位一定是0。
可以通過 number % 2 得到二進制形式的最後一位,如果要將一個完整的整數轉化為二進制就需要用到遞歸函數。
在遞歸調用之前,計算 number % 2的值,然後在遞歸調用語句之後進行輸出,這樣計算出的第一個數值反而在最後一個輸出。
為了得出下一個數,需要把原數除以2,這種計算相當於十進制下把小數點左移一位,如果此時得出的數是偶數,,則下一個二進制的數值是0,如果得出的是奇數,那麽下一個二進制數為1。
直到被2除的結果小於2,就停止遞歸。
void to_binary(unsigned int n) { unsigned int i = n % 2; if (n >= 2) to_binary(n / 2); printf("%c", i + 0x30); } |
斐波那契數列例子
斐波那契數列指的是這樣一個數列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...
第0項是0,第1項是第一個1。
這個數列從第2項開始,每一項都等於前兩項之和。
int fib(int n) { if (n == 0) return 0; if (n == 1) return 1; if (n > 1) return fib(n - 1) + fib(n - 2); } |
1.6.2 遞歸的優點
遞歸給某些編程問題提供了最簡單的方法
1.6.3 遞歸的缺點
一個有缺陷的遞歸會很快耗盡計算機的資源,遞歸的程序難以理解和維護。
C語言基礎-第五課-函數