
目錄
- 前言
- 函式定義
- 函式定義的另外一種寫法
- 函式具體使用
- return陳述句
- 函式宣告
- 函式的引數,值傳遞與址傳遞
- 函式遞回
- 解題思路
- 遞回原理圖
- 總結
前言
函式是什么,在我們初識C語言的時候,開始獨立撰寫自己的一個模塊,完成自己的任務,必然離不開函式,在工程中函式是一個分模塊的概念,但在了解函式的基礎上,進一步的認識你真的知道函式是什么嗎? 如果不太清楚請騰出閑暇時間了解一下作者的博客吧,必然會讓你有所識訓
如果在程式中定義了一個函式,在編譯時會把函式的源代碼轉換為可執行代碼并分配一段存盤空間,這段記憶體空間有一個起始地址,也稱為函式的入口地址,函式名代表函式的起始地址,呼叫函式時,從函式名得到函式的起始地址,并執行函式代碼,”
提示:以下是本篇文章正文內容,下面案例可供參考
函式定義
一:函式定義
函式定義就是函式體的實作,函式體就是一個代碼塊,他在函式被呼叫時被執行,函式的定義語法分為:
型別
函式名(形式引數)
函式體
函式回傳值
int main(void)
{
//函式體記憶體放代碼塊
return 0;
}
函式定義的另外一種寫法
這種宣告形式現在仍為標準所允許,主要是為了讓較老的程式無需修改就可以通過編譯,但我們應該提倡新的宣告風格,理由由二:他消除了舊式風格的冗余,其次,也是最重要的一點,它允許函式原型的使用,提高了編譯器在函式呼叫時檢查錯誤的能力
#include<stdio.h>
int * //回傳值為整形指標型別,注意回傳值型別并沒有與函式名寫在同一行
find_int(int key,int array[],int array_len)
{
int i = 0;
for(i = 0; i < array_len; i++)
{
/*
檢查這個位置的值是否是要被查找的值
*/
if(array[i] == key)
{
return &array[i]; //如果找到了就回傳此元素對應的地址
}
}
return NULL; // 沒有找到就回傳空
}
以上只是對函式的一個簡單的了解,函式究竟能干什么能不能為我們帶來便捷,看具體功能接下來逐步講解
函式具體使用
函式功能介紹:找出陣列中的指定元素key,并且回傳該元素的索引下標
#define _CRT_SECURE_NO_WARNINGS //微軟安全檢查
#include<stdio.h>
int functest(int arr[], int len, int key); //函式宣告,后面講解
//空格
int main()
{
int len = 0; //陣列長度
int key = 0; //需要查找的鍵值
int arr[] = { 1,2,3,4,5,6,7,8,9 }; // 初始化陣列
len = sizeof(arr) / sizeof(arr[0]);//求元素位元組
scanf("%d", &key);
int ret = functest(arr, len, key);//函式呼叫,回傳值由變數ret接受
printf("%d",ret);
return 0;
}
//良好的編程習慣是沒有關聯關系的代碼在中間可以加空格
int functest(int arr[], int len, int key)//函式的具體實作
{
int i = 0;
for (i = 0; i < len; i++)
{
if (arr[i] == key)
{
return i;//回傳指定元素的下標
}
}
}
用到的知識點:
函式回傳值
函式之間的值傳遞和地址傳遞
函式回傳值
隱藏的細節 len = sizeof(arr) / sizeof(arr[0]) 為什么要求出結果值后當作引數傳遞,為什么不能在int functest(int arr[], int len, int key) 直接求出陣列的總長度,直接參與計算,不要著急后面講解
return陳述句
當執行到達函式定義的末尾時,函式就會將執行玩的結果回傳(當然這個前提是函式回傳值不是void),也就是所函式執行完任務的時候會將回傳的結果帶回給主調函式,當然return陳述句可以在任意的位置,但是一個函式只會執行一次return陳述句,通常情況下,return陳述句運算式的型別就是函式宣告的回傳型別,只有當編譯器可以通過尋常算術轉換把運算式的型別轉換為函式宣告時的型別,才允許回傳型別和函式宣告的回傳型別不同的運算式
總結:
1、return陳述句可以有多條,但是return陳述句只會被執行一次
2、回傳值型別與函式宣告回傳值型別不同時,編譯器會將其隱士型別轉換為函式宣告時的型別
函式宣告
當編譯器遇到一個函式時,它產生代碼傳遞引數并呼叫這個函式,而且接受該函式的回傳的值(如果有的話)但編譯器時如何知道該函式是什么型別什么回傳值,多少引數數量的呢,其實向編譯器提供函式的資訊的方法時使用函式原型,原型總結了函式定義部分的起始部分的宣告,向編譯器提供該函式如何被呼叫的完整資訊,使用原型最方便的做法是將函式原型置于一個.h(頭檔案中),如果其他檔案需要參考直接呼叫就好,

函式原型

使用這鐘方式的好處是為了能夠便于維護和管理
函式的引數,值傳遞與址傳遞
C語言的函式均以 “傳值呼叫” 方式進行傳遞,這就意味著函式將獲得引數值的一份拷貝,這樣函式就可以放心修改這個拷貝值,而不必擔心修改呼叫程式實際傳遞給他的引數,但是,如果被傳遞的引數是一個陣列名,并且在函式中使用陣列下標修改陣列的元素值就會反饋到呼叫函式處的資訊,這個行為被稱為 ”傳址呼叫“
以下展示傳值呼叫和傳遞至呼叫的區別
//先來看傳值呼叫
#include<stdio.h>
#include"func.h"
void Swap(int val_1, int val_2) //值傳遞
{
int tmp = val_1;
val_1 = val_2;
val_2 = tmp;
printf("val1_1 = %d,val_2 = %d\n", val_1,val_2);
}
int main()
{
int a = 10, b = 20;
Swap(a, b);
printf("a = %d,b = %d\n", a, b);
}
運行結果可以看出值傳遞改變的只是實參傳遞給形參的一份臨時拷貝資料,但是這個臨時拷貝的資料并不會影響到我們的主程式

再來看我們的地址傳遞
#include<stdio.h>
#include"func.h"
void Swap1(int *val_1, int *val_2) //地址傳遞
{
int tmp = *val_1;
*val_1 = *val_2;
*val_2 = tmp;
printf("val1_1 = %d,val_2 = %d\n", val_1, val_2);
}
int main()
{
int a = 10, b = 20;
Swap(a, b);
printf("a = %d,b = %d\n", a, b);
}
實際觀察

F11進入Swap函式

函式被呼叫完回到主調函式

總結:
1、值傳遞只是一份實參傳遞給形參的臨時拷貝,臨時變數的修改不會直接反饋到主調函式
2、址傳遞之所以能夠修改實參變數的值是因為傳遞進去的是變數的地址,得到變數的地址進而再修改變數是會直接影響的
以下小知識有興趣可以了解一下,筆者也愿意將它分享出來

函式遞回
一個函式在它的函式體內呼叫它自身稱為遞回呼叫,這種函式稱為遞回函式,執行遞回函式將反復呼叫其自身,每呼叫一次就進入新的一層,當最內層的函式執行完畢后,再一層一層地由里到外退出,
空白的簡述不適于我們理解,下面上實體給看大家詳說遞回的細節,舉一道題目
撰寫一個函式 reverse_string(char * string)(遞回實作)

-
實作:將引數字串中的字符反向排列,不是逆序列印,
-
要求:不能使用C函式庫中的字串操作函式,
-
比如: 逆序之后陣列的內容變成:fedcba
//這是原字串
char arr[] = "abcdef";
解題思路
以遞回的方式將首字符與尾字符,逐個交換,將下標為0的第一個元素的值存入臨時變數中,末尾字符給\0,以此控制字串長度不斷縮減,使得不斷的接近遞回的終止條件,每層遞回都會存放tmp值至堆疊中(也叫現場值),等帶遞回終止后,挨個回傳回去,把堆疊中的值取出來,放到目標位置處
遞回原理圖


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<assert.h>
int my_strlen(const char *ptr)
{
int count = 0;
while (*ptr != '\0')
{
count++;
ptr++;
}
return count;
}
void reverse_string(char * string)
{
assert(string);
char *p = string;
int len = my_strlen(p) - 1;
char tmp = p[0];
p[0] = p[len];
p[len] = '\0';
if (my_strlen(p + 1) > 1)
{
reverse_string(p + 1);
}
p[len] = tmp;
return ;
}
int main()
{
char str[] = "abcdef";
reverse_string(str);
puts(str);
return 0;
}
以上就是今天要講的內容
總結
提示:這里對文章進行總結:
1、函式遞回是什么,遞回就是自己呼叫自己,遞回不能一直遞回,需要終止條件(出口)
2、return陳述句可以有多條,但是只會被執行一句return陳述句
3、實參傳遞給形參:使用傳值的方式,形參的改變不會影響到實參,而傳地址的方式,形參的改變會直接影響到主調函式
4、函式的宣告必須在最前面,這是提供給編譯器的一個資訊

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/290700.html
標籤:其他
上一篇:C語言提高(上)
