arg是什么函数_C 语言编程 — 函数
函數
函數的本質就是針對變量的操作過程,同時可能也會改變當前程序的狀態。它接受多個輸入值,計算并返回一個輸出值。
函數大體上分為 3 類:
函數的聲明
函數聲明就是告訴 C 編譯器函數的名稱、返回類型和參數以及如何調用函數。函數的實際主體可以單獨定義,但當你在一個源文件中定義函數且在另一個源文件中調用函數時,函數聲明是必需的。
聲明函數時,首先將返回值的類型寫在前面,后面緊跟函數的名字,而后的一對圓括號里面包裹函數的輸入參數,參數之間用 , 進行分割。
函數聲明包括以下幾個部分:
return_typefunction_name(parameter list);在函數聲明中,參數的名稱并不重要,只有參數的類型是必需的,因此下面兩種都是有效的聲明:
int max(int num1, int num2); int max(int, int);函數的定義
函數體部分緊跟其后,
函數定義除了定義函數的名稱、返回類型、形參列表之外,最重要的是編寫函數的主題,即函數體。包裹在 {} 里,里面包含了函數執行的所有語句,語句之間使用 ; 分隔。return 語句用來結束函數的執行,并返回一個值。
C 程序中函數的結構如下:
return_typefunction_name(parameter list){body of the function }- 返回類型:一個函數可以返回一個值,返回類型定義了函數返回的值的數據類型。有些函數不需要返回值,在這種情況下,return_type 是關鍵字 void。
- 函數名(函數標識符):函數名和參數列表一起構成了函數簽名。
- 形式參數:形參就像是占位符。當函數被調用時,向形參傳遞一個值,而這個值被稱為實際參數。形參列表包括函數參數的類型、順序、數量。形參是可選的,即形參列表可以為。
- 函數主體:包含了一組定義函數執行任務的語句。
函數的形參與實參
如果函數要使用參數,則必須聲明接受參數值的變量。這些變量稱為函數的形式參數。形式參數就像函數內的其他局部變量,在進入函數時被創建,退出函數時被銷毀。當調用函數時,有兩種向函數傳遞參數的方式:
- 值傳遞:該方法把參數的實際值復制給函數的形式參數。在這種情況下,修改函數內的形式參數不會影響實際參數。
- 引用傳遞:通過指針傳遞方式,形參為指向實參地址的指針,當對形參的指向操作時,就相當于對實參本身進行的操作。
值傳遞
默認情況下,C 語言使用傳值調用方法來傳遞參數。一般來說,這意味著函數內的代碼不會改變用于調用函數的實際參數。
- swap.c
- main.c
引用傳遞
通過引用傳遞方式,形參為指向實參地址的指針,當對形參的指向操作時,就相當于對實參本身進行的操作。傳遞指針可以讓多個函數訪問指針所引用的對象,而不用把對象聲明為全局可訪問。
- swap.c
- main.c
可變長形參列表
有時候我們需要函數帶有可變數量的參數,而不是預定義數量的參數。C 語言提供了 stdarg.h 頭文件,該文件提供了實現可變參數功能的函數和宏。
int func(int, ... ) {}int main() {func(1);func(1, 2);func(1, 2, 3);return 0; }- 定義一個函數,int 形參代表了要傳遞的可變參數的總數,... 可變長形參運算符標識函數的形參數量是可變的。
- 在函數定義中創建一個 va_list 類型變量,該類型是在 stdarg.h 頭文件中定義的。
- 使用 int 參數和 va_start 宏來初始化 va_list 變量為一個參數列表。宏 va_start 是在 stdarg.h 頭文件中定義的。
- 使用 va_arg 宏和 va_list 變量來訪問參數列表中的每個項。
- 使用宏 va_end 來清理賦予 va_list 變量的內存。
運行:
$ ./main Average of 2, 3, 4, 5 = 3.500000 Average of 5, 10, 15 = 10.000000函數的調用
定義 C 函數時,會定義函數做什么,然后通過調用函數來完成已定義的任務。當程序調用函數時,程序控制權會轉移給被調用的函數。被調用的函數執行已定義的任務,當函數的返回語句被執行時,或到達函數的結束括號時,會把程序控制權交還給主程序。
調用函數時,傳遞所需參數,如果函數返回一個值,則可以存儲返回值。
#include <stdio.h>/* 函數聲明 */ int max(int num1, int num2);int main () {/* 局部變量定義 */int a = 100;int b = 200;int ret;/* 調用函數來獲取最大值 */ret = max(a, b);printf( "Max value is : %dn", ret );return 0; }/* 函數返回兩個數中較大的那個數 */ int max(int num1, int num2) {/* 局部變量聲明 */int result;if (num1 > num2)result = num1;elseresult = num2;return result; }函數的指針
函數名本質就是一個地址,也就是一個指針。函數指針是指向函數的指針類型變量,函數指針可以像一般函數一樣,用于調用函數、傳遞參數。也就是說,函數指針其實可以看做就是一個函數的 “別名”。
函數指針很方便,可以作為實參傳入函數,在函數體中,僅僅通過指針就可以調用函數,這也是為了提高代碼的效率。函數指針和普通指針差不多,主要的區別是函數指針指向了特定的函數。
聲明一個函數指針:
typedef int (*fun_ptr)(int, int);e.g.
#include <stdio.h>int max(int x, int y){return x > y ? x : y; }int main(void){/* 定義并初始化一個函數指針 */int (*p)(int, int) = &max; // 可以省略地址運算符 &int a, b, c, d;printf("Input three numbers:");scanf("%d %d %d", &a, &b, &c);d = p(p(a, b), c); printf("MAX: %dn", d);return 0; }回調函數
回調函數就是將函數指針作為實參傳入到某個函數,即:回調函數就是一個通過函數指針調用的函數。
#include <stdlib.h> #include <stdio.h>void populate_array(int *array, size_t arraySize, int (*getNextValue)(void)) {size_t i;for(i = 0; i < arraySize; i++) {array[i] = getNextValue();} }int getNextRandomValue(void) {return rand(); }int main() {int i;int myarray[10];populate_array(myarray, 10, &getNextRandomValue); // & 可以省略,因為函數名的本質就是一個指針for(i = 0; i < 10; i++) {printf("%d ", myarray[i]);}printf("n");return 0; }遞歸函數
遞歸,指的是在函數的定義中調用函數自身。
void recursion() {statements;... ... ...recursion(); /* 函數調用自身 */... ... ... }int main() {recursion(); }但在使用遞歸時,一定要注意編寫退出條件,否則會進入死循環。遞歸函數在解決許多數學問題上起了至關重要的作用,比如計算一個數的階乘、生成斐波那契數列,等等。
數的階乘
#include <stdio.h>double factorial(unsigned int i) {if(i <= 1){return 1;}return i * factorial(i - 1); }int main() {int i = 15;printf("%d 的階乘為 %fn", i, factorial(i));return 0; }斐波那契數列
#include <stdio.h>int fibonaci(int i) {if (i == 0) {return 0;}if (i == 1) {return 1;}return fibonaci(i-1) + fibonaci(i-2); }int main() {int i;for (i = 0; i < 10; i++) {printf("%dtn", fibonaci(i));}return 0; }構造函數(Constructor)
構造函數 ,是一種特殊的方法。主要用來在創建對象時初始化對象, 即為對象成員變量賦初始值。例如:
- Java 中的 new 運算符
- Python 中的 __init__ 函數
通常的,一個類中只有一個構造函數;特別的,一個類可以有多個構造函數 ,可根據其參數個數的不同或參數類型的不同來區分它們即構造函數的重載。
析構函數(Destructor)
析構函數與構造函數相反,當對象結束其生命周期,如對象所在的函數已調用完畢時,系統自動執行析構函數。析構函數往往用來做 “清理善后” 的工作。
以 C++ 為例:析構函數名也應與類名相同,只是在函數名前面加一個位取反符~,例如:~stud( ),以區別于構造函數。它不能帶任何參數,也沒有返回值(包括 void 類型)。只能有一個析構函數,不能重載。如果用戶沒有編寫析構函數,編譯系統會自動生成一個缺省的析構函數(即使自定義了析構函數,編譯器也總是會為我們合成一個析構函數,并且如果自定義了析構函數,編譯器在執行時會先調用自定義的析構函數再調用合成的析構函數),它也不進行任何操作。所以許多簡單的類中沒有用顯式的析構函數。
C/C++學習資料分享交流群:1093776732 入群有全套學習視頻資料電子書免費贈送!
參考資料:
C語言編程基礎?www.makeru.com.cn七天提升C語言?www.makeru.com.cn七天提升C編程能力?www.makeru.com.cn夯實C語言,從小白到大牛的進階之路!?www.makeru.com.cn總結
以上是生活随笔為你收集整理的arg是什么函数_C 语言编程 — 函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python画代码流程图_Python使
- 下一篇: python类和对象详解_Python公