---
# System prepended metadata

title: 關於函式的一些事情
tags: [C++]

---

---
title: 關於函式的一些事情
tags: C++
---

# main函式
### 函式要先定義
c++編譯器在執行時**唯一會自動呼叫**的是 **``main 函式``**
所以如果有在 main 裡呼叫其他函式的話
一定要在main之前定義該函式
```cpp=
#include <iostream>
using namespace std;
int main(void){
    test();
    return 0;
}
void test(void){
    cout<<"Testing!";
}
```
上方就會報錯
```
正在開始建置...
"C:\Program Files\mingw64\bin\g++.exe" -fdiagnostics-color=always -g C:\Users\SUMESIN\Desktop\C++\things_aboout_function.cpp -o C:\Users\SUMESIN\Desktop\C++\things_aboout_function.exe
C:\Users\SUMESIN\Desktop\C++\things_aboout_function.cpp: In function 'int main()':
C:\Users\SUMESIN\Desktop\C++\things_aboout_function.cpp:4:5: error: 'test' was not declared in this scope
    4 |     test();
      |     ^~~~

建置已完成，但發生錯誤。
```
不過定義時可以不用寫很詳細
只要定義**回傳值跟參數**的型態就好
```cpp=
#include <iostream>
using namespace std;
void test(int);
int main(void){
    test();
    return 0;
}
void test(int a = 10){
    cout<<"Testing!"<<a;
}
```
>圖中有使用**預設參數**

### main的回傳值
在各個系統中 對 main 函式的回傳值有不同的動作
只有唯三結果才會一樣
其中一個就是代表函式順利執行的 ```0```
而且就算不寫回傳值
實際上會在底下進行例外處裡 執行成功的話就傳回 ```0```
```cpp=
int main(void){
    test();
}
```
# 傳參呼叫&傳值呼叫
### 傳值呼叫 ***Passed by value***
編譯器做的事是把傳入的資料複製一份
賦值給函數定義時使用的參數
然而遇到大資料時就會出問題
```cpp=
#include <iostream>
#include <string>
using namespace std;
void test(string);
int main(void){
    string a_large_string = "Pneumonoultramicroscopicsilicovolcanoconiosis";
    test(a_large_string);
    return 0;
}
void test(string large_string){
    cout<<large_string<<endl;
    cout<<"That's a large string";
}
```
### 傳參呼叫 ***Passed by reference***
遇到上面的問題時 就可以使用傳參呼叫
傳入的就是該**資料本身**  也就不會有複製的動作以及後續的問題
但是要注意的是 由於傳的是資料本身
所以在函式裡是會對資料進行修改的
```cpp=
#include <iostream>
#include <string>
using namespace std;
void test(string&);
int main(void){
    string a_large_string = "Pneumonoultramicroscopicsilicovolcanoconiosis";
    test(a_large_string);
    cout<<"but now, it's a small string"<<endl;
    cout<<a_large_string;
    return 0;
}
void test(string& large_string){
    cout<<large_string<<endl;
    cout<<"That's a large string"<<endl;
    large_string = "pneumoconiosis";
}
```
輸出為
```=
Pneumonoultramicroscopicsilicovolcanoconiosis
That's a large string       
but now, it's a small string
pneumoconiosis
```
如果不希望資料被修改  只希望讀取的話
可以使用 ==**const reference**==
```cpp=
#include <iostream>
#include <string>
using namespace std;
void test(const string&);
int main(void){
    string a_large_string = "Pneumonoultramicroscopicsilicovolcanoconiosis";
    test(a_large_string);
    cout<<"but now, it's a small string"<<endl;
    cout<<a_large_string;
    return 0;
}
void test(const string& large_string){
    cout<<large_string<<endl;
    cout<<"That's a large string"<<endl;
    large_string = "pneumoconiosis";
}
```
像上面就會報錯
:::danger
建置已完成，但發生錯誤。
:::


# inline 函式
可以在函式定義前加上 `inline` 關鍵字
告訴編譯器 在每次呼叫函式時
函式主體可以插入程式碼內 不用每次都執行正常的呼叫
這樣可以提高效率
```cpp
inline void test(string&);
```
但實際上 inline 關鍵字的作用**僅僅只是建議而已**
事實上就算你跟編譯器說這函式可以 inline
他也只會接受建議 實際會不會執行由編譯器自行決定
:::warning
因為有關這方面的優化 在c++中是屬於**編譯器的工作**
就算不給 inline 關鍵字 
編譯器也會照常自動決定函式是否需要 inline
:::
