內容提要
-
函數
-
函數的概述
-
函數的分類
-
函數的定義
-
形參和實參
-
函數的返回值
-
函數
函數的概述
-
函數:實現一定功能的,獨立的代碼模塊,函數是c程序的核心構成模塊,可以說c程序就是由眾多的函數組成,對于函數的使用,一定是先定義,后使用。
-
使用函數的優勢:
①可以通過函數提供給別人使用,也可以使用別人提供的函數,減少代碼量。
②借助函數可以減少重復性的的代碼。
③實現結構化(模塊化)程序設計思想
關于結構化設計思想:將大型的任務功能劃分為相互獨立的小型的任務模塊來設計。
-
函數是C語言程序的基本組成單元:
C語言程序是由一個或多個函數組成
函數的分類
-
從函數實現的角度:
-
庫函數:C語言標準庫實現的并提供使用的函數,比如:
scanf() printf() fgets() fputs() strlen()
-
自定義函數:需要程序員自行實現,開發中大部分函數都是自定義函數
-
-
從函數形式的角度:
-
無參函數:函數調用時,無需傳遞,可有可無返回值,舉例:
test1();
-
有參函數:函數調用時,需要參數傳遞數據,經常需要配套返回值來使用,舉例:
printf("%d\n",12);
-
-
從函數調用的角度:
-
主調函數:主動去調用其他函數的函數。(main函數只能作為主調函數)
-
被調函數:被其他函數調用的函數。
舉例:
?//主調函數int main(){//被調函數printf("hello world\n");}
很多時候,尤其是對于自定義函數來說,一個函數有可能既是主調函數,又是被調函數。
?int fun_b(){printf("hello\n");}?//主調函數int fun_a(){printf("world\n");//被調函數fun_b();}?int main(){//被調函數fun_a();}
以上案例中,fun_b()來說是主調函數,同時對于main()函數來說,它又是被調函數。
-
函數的定義
定義
語法:
?[返回類型] 函數名([形參列表]) ? ? ?------函數頭 ?| 函數首部{函數體語句; ? ? ? ? ? ? ? ? ? ------函數體,整個{}包裹的內容包括返回值都屬于函數體,{}不能省略}
函數頭:
-
返回類型:函數返回值的類型,(返回值是被調函數的主調函數)
-
函數名:函數的名稱,遵循標識符命名(不能以數字開頭,只能包含字母、數字、下劃線,建議:小寫+下劃線命名,舉例:show_all())
-
形參列表:用于接收主調函數傳遞的數據,如果有多個參數,使用“,”分隔,且每一個形參都需要指明類型。
小貼士:
形參列表(被調函數):主調函數給被調函數傳遞數據,主調函數 → 被調函數
返回類型(被調函數):被調函數給主調函數返回數據,被調函數 →主調函數
說明:
-
函數的返回類型:就是返回值的類型,兩個類型可以不同,但是必須能夠進行轉換,舉例:
?double fun_a() ? //函數的返回類型是double{return 12; ? //函數返回值是int}
以上代碼可以理解為:將int類型的12賦值給一個double類型的匿名變量(int → double),此時屬于隱式轉換。
?int fun_a() ? //函數的返回類型是double{return 12.5; ? //函數返回值是int}
案例:
??
-
在C語言中還可以定義無類型(void類型)的函數,這種函數不返回函數值(沒有函數值),只是完成某種功能,舉例:
?void test() ? ?//此時這個函數沒有返回值,也就是它的返回值是,return;{printf("hello\n");}?//下面等價于上面void test(){return; ?//一般,這個return是省略不寫的}
-
在C語言中,函數的返回類型是可以省略的,如果省略,默認返回int,舉例:
?//寫法1 main的返回類型是int類型,默認的返回值是0,等價于寫法2main(){...}?//寫法2:main的返回類型是int類型,默認的返回值是0int main(){return 0; ?// 0:邏輯真, -1:邏輯假 ? 支持非0表示}
-
函數中返回語句的形式為
return(表達式)
或者return 表達式
。//寫法1 int main() {return(0); }//寫法2 int main() {return 0; }
-
如果
參數列表
中有多個形式參數,則它們之間要用","分隔;即使它們的類型相同,在形式參數中只能逐個進行說明,舉例://正確寫法 int avg(int x, int y, int z) {... }//錯誤示例 int avg(int x,y,z) {... }
-
如果
形參列表
中沒有參數,我們可以不寫,也可以用void標識,舉例://寫法1 int main() {... }//寫法2 int main(void) {... }
案例
案例1
-
需求:計算1~n之間自然數的階乘
-
代碼:
注意:這里計算結果為0是因為數據太大,超過int存儲范圍,數據丟失
案例2
-
需求:計算一個圓臺兩個面的面積之和。
-
方案1:自定義一個函數,直接計算兩個圓的面積和
-
方案2:自定義一個函數,只計算一個圓的面積
-
代碼:
/*************************************************************************> File Name: demo02.c> Author: > Description: > Created Time: 2025年03月14日 星期五 14時26分54秒************************************************************************/#include <stdio.h> #include <math.h> #define PI 3.1415926// 對庫函數 extern double pow(double x,double y);/*** 定義一個函數,根據半徑計算面積* @param r :半徑* @return 面積*/ double cicle_area(double r) {return PI * pow(r,2.0);//編譯的時候,需要在gcc后面加-lm }int main(int argc,char *argv[]) {// 定義兩個圓半徑和兩個園面積double r1,r2,area1,area2;printf("請輸入兩個圓的半徑\n");scanf("%lf,%lf",&r1,&r2);//計算面積area1 = cicle_area(r1);area2 = cicle_area(r2);//輸出printf("一個園臺兩個面面積之和為:%.2f\n",area1 + area2);return 0; }
形參和實參
形參(形式參數)
函數定義時指定的參數,形參是用來接收數據的,函數定義時,系統不會為形參申請內存,只有當函數調用時,系統才會為形參申請內存,主要用于存儲實際參數,并且當函數同時(執行return),系統會自動回收為形參申請的內存資源。
案例
-
需求:判斷奇偶數
-
代碼:
/** * 方式1 */ void fun(int n) {if(n % 2 == 0){printf("%d是偶數\n",n);}else{printf("%d是奇數\n",n);} }/** * 方式2 推薦 */ void fun(int n) {if(n % 2 == 0){printf("%d是偶數\n",n);return;//return之后代碼不執行}printf("%d是奇數\n",n); }/** * 方式3 推薦 */ int fun(int n) {if(n % 2 == 0){printf("%d是偶數\n",n);return -1;//return之后代碼不執行}printf("%d是奇數\n",n);return 0; }
實參(實際參數)
定義
-
函數調用時主調函數傳遞的數據參數(字面量、符號常量、表達式...,是要是確定的值),實參就是傳遞的數據。
-
實參和形參必須類型相同,如果不同時,按賦值規定進行類型轉換,比如隱式轉換。
-
在C語言中,實參傳遞必須遵循
單向傳遞
(通過實參給形參賦值),實參只是將自身的值傳遞給了形參,而不是實參本身,形參的值的改變不會影響實參。int fun(int n) {printf("%d\n",n); }int main() {int a = 10; // a = 10fun(a); // a是實參,數據10,實參是變量a = 20; //a = 20fun(12);//字面量12就是實參fun(a + 12); //數據量是22 實參是表達式 }
-
實參與形參在內存中占據不同的內存空間。
double fabs(double a) {return a < 0 ? -a : a; }int main() {int x = 12,y = -12;int x1 = (int)fabs(x); //12int y1 = (int)fabs(y); //12 }
案例
案例1:
-
需求:輸入4個整數,要求用一個函數求出最大數
-
代碼:
/*************************************************************************> File Name: demo03.c> Author: > Description: > Created Time: 2025年03月14日 星期五 15時25分32秒************************************************************************/#include <stdio.h>/*** 定義一個函數,求兩個數最大數* @param x,y* @return 最大數*/ int max(int x, int y) {return x > y ? x : y; }int main(int argc,char *argv[]) {int a,b,c,d,max1,max2,max3;printf("輸入4個數\n");scanf("%d%d%d%d",&a,&b,&c,&d);//求abmax1 = max(a,b);//求abcmax2 = max(max1,c);//求abcdmax3 = max(max2,d);printf("%d,%d,%d,%d中最大%d\n",a,b,c,d,max3);return 0; }
函數的返回值
-
若不需要返回值,函數可以沒有return語句。
//如果返回類型是void,return可以省略 void fun1 {}//return 可以省略,默認 0 int fun2() {} //return 可以省略,默認 0 fun3() {}
-
一個函數中可以有多個return語句,但任一時刻只有一個return語句被執行
int eq(int num) {if(num % 2 == 0){printf("%d\n",num);return 0;}printf("%d\n",num);return 0; }
-
返回值類型一般情況下要和函數中return語句返回的數據類型一樣,如果不一致,以函數定義時指定的返回值類型為標準。
案例
需求:輸入兩個整數,要求用一個函數求最大數
-
案例1:
/*************************************************************************> File Name: demo04.c> Author: > Description: > Created Time: 2025年03月14日 星期五 16時01分54秒************************************************************************/#include <stdio.h>/*** 定一個函數* @param x,y* @return max*/ int get_max(int x, int y) {if (x > y) return x;return y; }int main(int argc,char *argv[]) {int a,b,max;printf("請輸入\n");scanf("%d%d",&a,&b);max = get_max(a,b);printf("%d,%d中最大數是%d\n",a,b,max);return 0; }
-
案例2
/*************************************************************************> File Name: demo05.c> Author: > Description: > Created Time: 2025年03月14日 星期五 16時01分54秒************************************************************************/#include <stdio.h>/*** 定一個函數* @param x,y* @return max*/ double get_max(int x, int y) {if (x > y) return x;return y; }int main(int argc,char *argv[]) {int a,b,max;printf("請輸入\n");scanf("%d%d",&a,&b);max = (int)get_max(a,b);printf("%d,%d中最大數是%d\n",a,b,max);return 0; }
-
案例3:
/*************************************************************************> File Name: demo06.c> Author: > Description: > Created Time: 2025年03月14日 星期五 16時01分54秒************************************************************************/#include <stdio.h>/*** 定一個函數* @param x,y* @return max*/ double get_max(int x, int y) {double z;z = x > y ? x : y;return (int)z; }int main(int argc,char *argv[]) {int a,b,max;printf("請輸入\n");scanf("%d%d",&a,&b);max = get_max(a,b);printf("%d,%d中最大數是%d\n",a,b,max);return 0; }
運行結果: