您好,登錄后才能下訂單哦!
本篇內容介紹了“C語言函數有哪些及怎么定義使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
維基百科中對函數的定義:子程序
在計算機科學中,子程序(英語:Subroutine, procedure, function, routine, method,subprogram, callable unit),是一個大型程序中的某部分代碼, 由一個或多個語句塊組成。它負責完成某項特定任務,而且相較于其他代 碼,具備相對的獨立性。
一般會有輸入參數并有返回值,提供對過程的封裝和細節的隱藏。這些代碼通常被集成為軟件庫。
庫函數
自定義函數
在學習C語言編程時,總是在一個代碼編寫完成之后,想把這個結果打印到屏幕上看看。這時使用一個功能:將信息按照一定的格式打印到屏幕上(printf)。
在編程的過程中我們會頻繁的做一些字符串的拷貝工作(strcpy)
在編程是我們也計算,總是會計算n的k次方這樣的運算(pow)
上面的函數不用自己編寫,直接可以調用。為了支持可移植性和提高程序的效率,所以C語言的基礎庫中提供了一系列類似的庫函數,方便程序員進行軟件開發。
C語言常用的庫函數都有:
IO函數
字符串操作函數
字符操作函數
內存操作函數
時間/日期函數
數學函數
其他庫函數
使用庫函數,必須包含 #include 對應的頭文件。
推薦查詢工具官網:
MSDN(Microsoft Developer Network)
www.cplusplus.com
自定義函數和庫函數一樣,有函數名,返回值類型和函數參數。這些都是我們自己來設計,函數的組成:
ret_type fun_name(para1, * ) { statement;//語句項 } //ret_type 返回類型 //fun_name 函數名 //para1 函數參數
//舉例:寫一個函數可以找出兩個整數中的最大值 //get_max函數的設計 int get_max(int x, int y) { return (x>y)?(x):(y); } int main() { int num1 = 10; int num2 = 20; int max = get_max(num1, num2); printf("max = %d\n", max); return 0; }
真實傳給函數的參數,叫實參
實參可以是:常量、變量、表達式、函數等
無論實參是何種類型的量,在進行函數調用時,它們都必須有確定的值,以便把這些值傳送給形參
形式參數是指函數名后括號中的變量,因為形式參數只有在函數被調用的過程中才實例化(分配內存單元),所以叫形式參數
形式參數當函數調用完成之后就自動銷毀了。因此形式參數只在函數中有效
//舉例2:寫一個函數可以交換兩個整形變量的內容 //實現成函數,但是不能完成任務 int exchange1(int x, int y) {//當實參傳給形參時候,形參是實參的一份臨時拷貝, //對形參的修改不會影響實參 int temp = x; x = y; y = temp; } //正確的版本 int exchange2(int* pa, int* pb)//定義指針,接收地址 { int temp = *pa; *pa = *pb; *pb = temp; } int main() { int a = 3; int b = 5; exchange1(a, b);//傳參是值 printf("exchange1::a = %d b = %d\n", a, b);//交換前 exchange2(&a, &b);//傳參是地址 printf("exchange2::a = %d b = %d\n", a, b);//交換后的 //傳入地址,自定義的形參和實參聯系更加緊密,能改變地址存儲的數值 //此時,形參的地址與實參的地址是一樣的 return 0; }
上面代碼中, exchange1和 exchange2函數中的參數 x,y,pa,pb 都是形式參數。在main函數中傳給 exchange1的 a ,b 和傳給 exchange2函數的 &a ,&b是實際參數。
運行結果如下所示,exchange1并沒有起到預想的交換數值的作用,exchange2可以。
通過監視變量發現:
名稱 | 值 | 意義 |
---|---|---|
a | 5 | 數值為5 |
&a | 0x113f8e4 | 數值a的地址 |
x | 5 | 形參x數值為5 |
&x | 0x113f800 | 形參x的地址 |
pa | 0x113f8e4 | 形參pa數值為a的地址 |
變量a在內存中開辟了空間,地址是0x113f8e4
函數exchange1將實參a傳遞給形參x,x的數值也是5,但此時形參x另外重新再內存中開辟了空間,地址 0x113f800,形參和實參的地址是不一樣的
函數exchange2將實參a傳遞給形參pa,pa的值是變量a的地址0x113f8e4,這個地址里面存放變量a的數值5。
這里可以看到 exchange1函數在調用的時候, x , y 擁有自己的空間,同時擁有了和實參一模一樣的內容。所以我們可以簡單的認為:
形參實例化之后其實相當于實參的一份臨時拷貝。形參x、y的值發生交換,但是不影響實參a、b的值。一般性的只是使用數值大小,利用形參傳值就可以了,傳值表明,形參和實參的關系膚淺,僅限于表面數值的拷貝。
如果需要對主函數的實參值進行操作,比如交換,此時形參需傳地址,功能更為強大。傳地址表明,形參和實參的關系更深一步,直接可以通過地址修改實參的數值。
函數的形參和實參分別占有不同內存塊,對形參的修改不會影響實參。
傳址調用是把函數外部創建變量的內存地址傳遞給函數參數的一種調用函數的方式
這種傳參方式可以讓函數和函數外邊的變量建立起真正的聯系,也就是函數內部可以直接操作函數外部的變量
寫一個函數可以判斷一個數是不是素數
//返回1 表示是素數 //返回-1 表示不是素數 //寫法1 2-n-1 試除法 int is_sushu(int a) {//素數就是除1和自身外,不能被其他數整除 for (int i = 2; i < a-1; i++) {//用2-n-1的數一一試除 if (a%i==0) {//若有能除的,直接返回-1,跳出后面的循環了 return -1;//表明不是素數, } }//break退出循環會調到這里 //return返回時直接退出這個函數了,返回到主函數了,級別更高 return 1; } int main() { int a = 0; scanf("%d", &a); int num = is_sushu(a); if (num==1) { printf("%d: 是素數", a); } else { printf("%d:不是素數", a); } return 0; } //寫法2 2-sqrt(n) 試除法,速度更快 #include<math.h> int is_sushu(int num) { for (int i = 2; i <=sqrt(num); i++) { if (num%i == 0) { return -1; } } return 1; } int main() { int num = 0; for (int num = 100; num < 201; num++) { if ((is_sushu(num)) == 1) { printf("%d ", num); } } return 0; }
寫一個函數判斷一年是不是閏年
//閏年時是4的倍數且不是100的倍數,或者是400的倍數 int is_run_nian(int y) { if (((num%4 == 0)&& (num%100 != 0))|| (num % 400 == 0)) { return 1; } //return ((num%4 == 0)&& (num%100 != 0))|| (num % 400 == 0);//簡寫 } int main() { int num = 0; for (int num = 1000; num <= 2000; num++) { if ((is_run_nian(num)) == 1) { printf("%d ", num); } } return 0; }
寫一個函數,實現一個整形有序數組的二分查找
//找到了就返回下標 //找不到返回-1 int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; int k = 0; int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); int left = 0;//左下標 int right = sz - 1;//右下標 scanf("%d", &k); while (left<=right) {//每次left right mid都要更新 int mid = left + (right - left) / 2; if (arr[mid] > k) {//尋找的數值在左半邊,所以左不動,右邊動 right = mid - 1; } else if (arr[mid] < k) {//尋找的數值在右半邊,所以左邊動,右不動 left = mid + 1; } else { printf("找到了:%d ", mid); break; } } if (left>right)//循環結束了 { printf("找不到"); } return 0; }
可以將二分法進行改進,寫成獨立的函數,讓函數功能單一化:
int is_erfen(int arr[],int k, int sz) {//數組傳遞參數進來就是數組首元素的地址,并不是整個數組 //地址的大小是4或8個字節,前面有講到過的 //x86平臺中,地址占4個字節,sizeof(arr)是4, 而不是40了 //int sz = sizeof(arr) / sizeof(arr[0]);//sz要在主函數計算, int left = 0; int right = sz - 1; while (left <= right) {//每次left right mid都要更新 int mid = left + (right - left) / 2; if (arr[mid] > k) { right = mid - 1; } else if (arr[mid] < k) { left = mid + 1; } else { return mid; } } return -1; } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; int k = 0; int i = 0; scanf("%d", &k); //主函數中 按數組名找到整個數組,求出占用字節是40 int sz = sizeof(arr) / sizeof(arr[0]); int num = is_erfen(arr, k, sz); if (num ==-1) { printf("找不到"); } else { printf("找到了:%d ", num); } return 0; }
在上面的函數中需要注意,數組的大小必須在主函數中計算,下面代碼可說明在主函數中和其他函數中求數組長度的區別:
int erfen(int arr[]) {//數組傳遞進來,只能是首地址,這個arr數組里只有{1},長度為4 int sz1 = sizeof(arr) / sizeof(arr[0]);,//4/4 = 1求出只有1個元素 printf("erfen求數組大小,sz1:%d\n ", sz1); } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; //數組長度為40 int sz = sizeof(arr) / sizeof(arr[0]);//40/4 = 10 求出數組10個元素 printf("main中求數組大小,sz:%d\n ", sz); erfen(arr); return 0; }
按F10進入調試界面,按F11,可觀察到:
主函數中sizeof(arr)長度是40,數組中包含10個元素。
而在函數erfen中,sizeof(arr)長度是4,數組中包含1個元素,就是首元素{ 1 }。
由此,可知道,參數里傳遞數組時,實際傳遞的數組就是數組的地址,也是數組首元素的地址。數組名傳遞進來,只能是首地址,這個arr數組里只有首元素{1},長度為4。整個數組是傳遞不了的。因此,必須在主函數里求取數組的長度。
因為傳遞的參數是地址,所以erfen中也可以定義指針來接受數組:
//int erfen(int arr[])//接受數組,只能接受一個首元素 int erfen(int* arr) {//數組傳遞進來,只能是首地址,這個arr數組里只有{1},長度為4 int sz1 = sizeof(arr) / sizeof(arr[0]);,//4/4 = 1求出只有1個元素 printf("erfen求數組大小,sz1:%d\n ", sz1); } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; //數組長度為40 int sz = sizeof(arr) / sizeof(arr[0]);//40/4 = 10 求出數組10個元素 printf("main中求數組大小,sz:%d\n ", sz); erfen(arr); return 0; }
運行結果一樣
寫一個函數用一次這個函數,就會將 num 的值增加1
int add(int* p) { (*p)++;//參數傳地址,可以操作實參的值 } int main() { int a = 10; add(&a);//傳地址 printf("%d\n", a); add(&a); printf("%d\n", a); add(&a); printf("%d\n", a); add(&a); printf("%d\n", a); return 0; }
函數和函數之間可以根據實際的需求進行組合的,也就是互相調用的。
//套娃 void newline() { printf("hehe\n"); } void threeline() { int i = 0; for (int i = 0; i < 3; i++) { newline(); } } int main() { threeline(); newline; return 0; }
把一個函數的返回值作為另外一個函數的參數。
int main() { char arr[20] = "hello"; int ret = strlen(strcat(arr, "bit")); printf("%d\n", ret); return 0; } int main() { printf("%d", printf("%d", printf("%d", 43)));//輸出4321, //前面是打印43 2是返回兩個字符(因為4 、3是兩個字符) //1是返回1個字符(2是1個字符) return 0; }
輸出結果見下圖:
“C語言函數有哪些及怎么定義使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。