一:庫函數
1.庫函數的介紹
我們前⾯內容中學到的 printf 、 scanf 都是庫函數
庫函數相關頭⽂件:https://zh.cppreference.com/w/c/header
2.庫函數的使⽤⽅法
C/C++官⽅的鏈接:https://zh.cppreference.com/w/c/header cplusplus.com:https://legacy.cplusplus.com/reference/clibrary/
舉例:sqrt
sqrt需要的頭文件
#include<math.h>
#include//sqrt需要的頭文件
int main()
{
double ret = sqrt(100);//sqrt作用是 計算平方根 ret是返回值的意思 sqrt屬於浮點型
printf("%f\n", ret);
return 0;
}
3.頭⽂件包含
庫函數是在標準庫中對應的頭⽂件中聲明的,所以庫函數的使⽤,務必包含對應的頭⽂件,不包含是 可能會出現⼀些問題的
練習:
#include
#include
int main()
{
double d = 16.0;
double r = sqrt(d);
printf("%lf\n", r);
return 0;
}
輸出結果:
二:自定義函數
1.函數的語法形式
- ret_type 是函數返回類型 , 是⽤來表⽰函數計算結果的類型,有時候返回類型可以是 void ,表⽰什麼都不返回
- fun_name 是函數名, 是為了⽅便使⽤函數;就像⼈的名字⼀樣,有了名字⽅便稱呼,函數有了名字⽅便調 ⽤,所以函數名儘量要根據函數的功能起的有意義
- 括號中放的是形式參數
- {}括起來的是函數體
ret_type fun_name(形式參數)
{
}
練習:
問題:寫一個加法函數,完成2個整型函數的加法操作
正常的計算方法
正常的計算方法
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);//輸入值
int c = a + b;//將a和b加起來存入c當中
printf("%d\n", c);//將最終的c的輸出值打印出來
return 0;
}
引用函數的計算方法
函數的定義(創造函數)
int Add (int x, int y)//因為a和b屬於整型,因此這裏的兩個參數形式用整型,x對應a y對應b
{ //返回類型 函數名 形式參數
int z = 0;//將相加後參數的結果存放到z裏面去
z = x + y;//將2個參數相加
return z;//將參數的結果值返回到下面的int c裏面去 這裏的return z屬於int 類型,所以我們Add函數也應該是整型,要保持一致
}
上面的代碼還可以優化一下
int Add(int x, int y)
{
return x + y;//直接將兩個參數相加的值返回到c裏面去
}
主函數
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);//輸入值
int c = Add(a, b);//函數的調用(使用函數)然後完成a和b的加法運算,並且將最終的結果存入c裏面去,這裏Add中文意思是 ‘加’,我們在設置函數名字的時候應該要有意義
printf("%d\n", c);//將最終的c的輸出值打印出來
return 0;
}
完整的代碼
int Add(int x, int y)
{
return x + y;//直接將兩個參數相加的值返回到c裏面去
}
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);//輸入值
int c = Add(a, b);//函數的調用(使用函數)然後完成a和b的加法運算,並且將最終的結果存入c裏面去,這裏Add中文意思是 ‘加’,我們在設置函數名字的時候應該要有意義
printf("%d\n", c);//將最終的c的輸出值打印出來
return 0;
}
輸出結果
練習:
注意:不需要任何返回類型以及參數
問題:用這樣的形式打印一個hehe
後面的void是不傳入參數的意思,如果我們在下面那個print函數後面加了參數,那麼會報錯誤的
前面那個void是不需要返回類型
有了void就不用傳入參數, 我們只是調用這個函數
print();
完整代碼
void print(void)
{
printf("hehe\n");
}
int main()
{
print();//有了void就不用傳入參數, 我們只是調用這個函數
return 0;
}
輸出結果
三:函數的形參和實參
在函數使⽤的過程中,把函數的參數分為,實參和形參
1.實參
再看看我們前⾯寫的代碼:
int main以上的代碼是 Add 函數的定義
int Add(int x, int y)
{
return x + y;//直接將兩個參數相加的值返回到c裏面去
}
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);//輸入值
int c = Add(a, b);//函數的調用(使用函數)然後完成a和b的加法運算,並且將最終的結果存入c裏面去,這裏Add中文意思是 ‘加’,我們在設置函數名字的時候應該要有意義
printf("%d\n", c);//將最終的c的輸出值打印出來
return 0;
}
函數的調用(使用函數)然後完成a和b的加法運算,並且將最終的結果存入c裏面去,這裏Add中文意思是 ‘加’,我們在設置函數名字的時候應該要有意義
調⽤Add函數時,傳遞給函數的參數a和b,稱為實際參數,簡稱實參
int c = Add(a, b);
2.形參
函數名Add 後的括號中寫的 x 和 y ,稱為形式參數
為什麼叫形式參數呢?實際上,如果只是定義了 Add 後的括號中寫的 x 和 y ,⽽不去調⽤的話, Add 函數的參數 x 和 y 只是形式上存在的,不會向內存申請空間,不會真實存在的,所以叫形式參數。形式參數只有在 函數被調⽤的過程中為了存放實參傳遞過來的值,才向內存申請空間,這個過程就是形參的實例化。
int Add(int x, int y)
{
return x + y;//直接將兩個參數相加的值返回到c裏面去
}
3.形參與實參的關係
看下面代碼
int Add(int x, int y)//x y 是形式參數,簡稱形參
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);//輸入值
int c = Add(a, b);//a b 是真實傳遞給Add函數的參數 所以a b 是實參(實際參數)
printf("%d\n", c);
return 0;
}
我們在調試的時候可以觀察到,x和y確實得到了a和b的值,但是x和y的地址和a和b的地址是不⼀樣 的,所以我們可以理解為形參是實參的⼀份臨時拷⻉。
四:return 語句
在函數的設計中,函數中經常會出現return語句,這⾥講⼀下return語句使⽤的注意事項
- return後邊可以是⼀個數值,也可以是⼀個表達式,如果是表達式則先執⾏表達式,再返回表達式 的結果。
- return後邊也可以什麼都沒有,直接寫 return; 這種寫法適合函數返回類型是void的情況。
- return語句執⾏後,函數就徹底返回,後邊的代碼不再執⾏。
- return返回的值和函數返回類型不⼀致,系統會⾃動將返回的值隱式轉換為函數的返回類型。
- 如果函數中存在if等分⽀的語句,則要保證每種情況下都有return返回,否則會出現編譯錯誤。
- 函數的返回類型如果不寫,編譯器會默認函數的返回類型是int。
- 函數寫了返回類型,但是函數中沒有使⽤return返回值,那麼函數的返回值是未知的。
這裏部分注意事項用代碼給大家展開看下
1.return後面可以什麼都沒有,直接寫return; 這種寫法適合函數返回類型是void的情況
問題:計算1到n所有數相加後的值
代碼如下
void test(int n)
{
if (n <= 0)
return;//直接結束後面的代碼,不去執行,和break有一點相似
int i = 0;
int sum = 0;//將最終求和的值存放裏面去
for (i = 1; i <= n; i++)
{
sum += i;//將每一個數加起來,相當於求和
}
printf("%d\n", sum);//結果是15
}
int main()
{
test(5);//隨便給個參數
return 0;
}
輸出結果
直接結束後面的代碼,不去執行,和break有一點相似
return;
隨便給個參數
test(5);
2.return返回的值和函數返回類型不一致,系統會自動將返回的值偷偷的轉換為函數的返回類型
代碼如下
int test()
{
return 3.14;//返回值為浮點型,但是我們是int 整型,所以輸出的結果本身3.14而是3 我們應該將return的返回值和函數返回類型保持一致
}
int main()
{
int r = test();
printf("%d\n", r);//結果是3
return 0;
}
輸出結果:
3.如果函數中存在if等分支語句,則要保證每種情況下都有return返回,否則會報錯誤
問題:函數用來判斷n是奇數還是偶數,是奇數則返回1,是偶數就返回0
代碼如下:
int test(int n)
{
if (n % 2 == 1)
return 1;
else
return 0;//如果沒有這個代碼,當我們的n是6的時候,return不知道返回什麼值,因此會報錯誤
}
int main()
{
int ret = test(6);//
return 0;
}
如果沒有這個代碼,當我們的n是6的時候,return不知道返回什麼值,因此會報錯誤
return 0;
五:數組做函數參數
問題:寫一個函數將arr數組的內容全部設置為-1,並且將其內容打印出來
1.設置數組
void set_arr(int arr1[], int sz1)//這裏的 _ 是為了更好的看函數名字,加不加無所謂的,如果你去掉 _ 那麼你不能加空格來讓它們美觀
{ //參數1 參數2
int i = 0;
for (i = 0; i < sz1; i++)
{
arr1[i] = -1;
}
}
括號第一個是參數1 後面是參數2
void set_arr(int arr1[], int sz1)
這裏的 _ 是為了更好的看函數名字,加不加無所謂的,如果你去掉 _ 那麼你不能加空格來讓它們美觀,要麼加_ 要麼就不加,讓它們完全挨在一起,但是這樣不好看,所以建議加上
void set_arr
2.打印數組
打印數組
void print_arr(int arr1[], int sz1)//arr2後面的括號可以省略,這樣可以接受任意大小的數組
{ //形參
int i = 0;
for (i = 0; i < sz1; i++)
{
printf("%d ", arr1[i]);//打印數組第i個元素的值
}
printf("\n");//換行,使輸出值更加美觀
}
3.主函數
int main()
{
int arr1[10] = { 0 };//初始化為0,可以存放10個元素
int sz1 = sizeof(arr1) / sizeof(arr1[0]);//計算數組元素個數
print_arr(arr1, sz1);//第一次調用打印函數,輸出10個0
實參
set_arr(arr1, sz1);//調用設置函數,把所有的元素改為-1
print_arr(arr1, sz1);//第二次調用打印函數,輸出10個-1
return 0;
}
完整代碼如下:
設置數組
void set_arr(int arr1[], int sz1)//這裏的 _ 是為了更好的看函數名字,加不加無所謂的,如果你去掉 _ 那麼你不能加空格來讓它們美觀
{ //參數1 參數2
int i = 0;
for (i = 0; i < sz1; i++)
{
arr1[i] = -1;
}
}
//打印數組
void print_arr(int arr1[], int sz1)//arr2後面的括號可以省略,這樣可以接受任意大小的數組
{ //形參
int i = 0;
for (i = 0; i < sz1; i++)
{
printf("%d ", arr1[i]);//打印數組第i個元素的值
}
printf("\n");//換行,使輸出值更加美觀
}
//
int main()
{
int arr1[10] = { 0 };//初始化為0,可以存放10個元素
int sz1 = sizeof(arr1) / sizeof(arr1[0]);//計算數組元素個數
print_arr(arr1, sz1);//第一次調用打印函數,輸出10個0
// 實參
set_arr(arr1, sz1);//調用設置函數,把所有的元素改為-1
print_arr(arr1, sz1);//第二次調用打印函數,輸出10個-1
return 0;
}
輸出結果: