###### tags: `FoShiShi`
# 函式
## What
函式可以用來**執行一段程式碼、中途跳出函式、回傳東西**
:::info
**主函式(main)也是函式**
:::
例:三角函數可以回傳角度對應的三角比值,`max(a, b)`可以回傳`a`跟`b`中較大的那個值
:::info
通常把不是主函式(main)的函式
稱作為 **副函式**
:::
## When
當你想要把一串動作做成一個獨立的函式時
可以**讓主函式(main)中的程式碼不那麼亂**
## How
函式的宣告跟主函式(main)一樣
可以寫成以下的方式:
```cpp=
// 宣告
回傳型態 函式名稱(資料型態1 引用值1, 資料型態2 引用值2, .... , 資料型態n 引用值n) {
要執行的東東;
return 回傳值;
}
//呼叫
函式名稱(引用值1, 引用值2, .... , 引用值n)
```
例:
```cpp=
int func() {
return 100;
}
int main() {
cout << func() << endl; // 100
}
```
:::warning
副函式**必須宣告在主函式之外**
然後只能在函式中呼叫其他函式
並且所引用的函式必須宣告在此函示之上
例:
```cpp=
int a() {
return 0;
}
int b() {
return 1;
}
```
**可以在`b`中呼叫`a`函式**
**但不能在`a`中呼叫`b`函式**
:::
:::success
回傳就是
在別的地方呼叫了函式,函式就要回傳一個值給這個地方
可以想成一種回饋
你給一台機器按了一連串的按鈕當 **引用值**
他就會在最後顯示一個對應的東西當 **回傳值**
:::
:::info
如果不想回傳東西,可以把回傳型態設為`void`
然後在回傳的時候`return`後面就什麼都不要加
例:
```cpp=
void f() {
cout << "aaa" << endl;
return;
}
```
在所有函式中
**當我們呼叫`return`的時候將直接中止此函式**
如果想要中途跳出函式可以這樣做
:::
當我們呼叫函式時,我們可以**傳入一些引用值**(當然也可以不用),然後**利用引用值來得出要回傳的東西**
例:
```cpp=
int min(int a, int b) {
if(a < b) {
return a;
}
else {
return b;
}
}
int main() {
int x = 10, y = 9;
cout << min(x, y) << endl; // 9
}
```
:::warning
當我們把一值引用到另一函式時,它的名稱不必相同(如下,我們把`x`丟進去,但在函式裡面的值的名稱是`a`)
**如果在函式中改變了引用值的值,他不會改變到函式外拿來傳入的值**
例:
```cpp=
void f(int a) {
a = 10;
return;
}
int main() {
int x = 5;
cout << x << endl; // 5
f(x);
cout << x << endl; // 5
}
```
:::
## 區域&全域變數
### 全域變數
我們可以**把一些值宣告在所有函式(包括主函式)的外面**
我們就稱他為全域變數(全域內區域外名稱不可重複)
這樣在他宣告的那一行之下的各種操作皆可使用該值
例:
```cpp=
int a = 10;
void f() {
cout << a << endl;
return;
}
int main() {
cout << a << endl; // 10
f(a); // 10
}
```
### 區域變數
當我們**把值宣告在任意函式中(包括主函式)**
我們就稱他為區域變數(區域內名稱不可重複)
這樣在他宣告的函式中的那一行之下的各種操作皆可使用該值(僅限該函式內)
(引用到函式中的值也算區域變數)
例:
```cpp=
void f() {
int a = 10;
cout << a << endl;
}
int main() {
cout << a << endl; // error: cant find variable "a"
f(); // 10
}
```
那當我們要使用一個值,但該值的明稱同時在區域跟全域同時存在時,會是哪個值呢?
**在出現這個狀況時,程式會使用的是區域變數**
例:
```cpp=
int a = 5;
void f() {
cout << a << endl;
}
int main() {
int a = 10;
cout << a << endl; // 10
f(); // 5
}
```
因為這很容易混淆,所以題目很常出
## 實際應用
### 題目1
建構一個函式
引入兩值
回傳兩值中的較大者
:::spoiler solution
把函式宣告在`main`外面
用`if`去判斷哪個比較大
```cpp=
#include<iostream>
using namespace std;
int max(int a, int b) {
if(a > b) {
return a;
}
else {
return b;
}
}
int main() {
...
}
```
:::
### 題目2
建構一個函式
引入三值(`a, b, c`)
回傳`a + b`是否為`c`的倍數(`true or false`)
:::spoiler solution
回傳型態用`bool`
用`%`判斷是否為倍數
```cpp=
#include<iostream>
using namespace std;
bool max(int a, int b, int c) {
if((a + b) % c == 0) {
return true;
}
else {
return false;
}
}
int main() {
...
}
```
:::