---
# System prepended metadata

title: 程式設計培訓 - 筆記(1)
tags: [presentation]

---

---
title: 程式設計培訓 - 筆記(1)        # 簡報的名稱
tags: presentation   # 簡報的標籤
slideOptions:        # 簡報相關的設定
  theme: solarized   # 顏色主題
  transition: 'fade' # 換頁動畫
  # parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'
---
<style>
.reveal .slides {
    text-align: left;
}
</style>

## 函式

C 語言中，可以把需要重複寫的程式提出來寫成函式(function)，而需要的時候直接呼叫這個函式就好，也就是模組化的概念。

什麼叫模組化？簡單來說，就是把特定功能分出來當成一個模組，需要的時候只要呼叫這個模組就好；而需要修正的時候也只要修正模組即可。

架構:

```cpp=
型態 函式名稱(參數){
    程式區塊;
}
```

例如，我們可以把**輸出hello world**寫成一個函式，格式如下:

```cpp=
#include<iostream>

void printhello(){
    printf("hello world");
}

int main()
{
    printhello();
    
    return 0;
}

/*輸出:
hello world
*/
```

第一，**函式要寫在主函式(main)外**，第二，**最好寫在主函式下方**，第三，**要在標頭檔下方就先宣告**，第四，**函式可以呼叫很多次**，第五，**參數要對好**。

那其實函式也有分型態，甚麼意思呢?

我們再來看一次函式的架構:

```cpp=
資料型態 函式名稱(參數)
{
    程式內容
}
```

那代表函式也有所謂的"資料型態"，那其實也只是分**是否有回傳值**。
* 有回傳值 : int, bool, ...。
* 沒回傳值 : void  。

那有回傳的資料型態我們要怎麼判斷呢?

由**回傳值**判斷，若回傳值是一個整數，那函式的資料型態就會是**int**，如果是布林值，則資料型態就會是**bool**...依此類推，那回傳我們會利用**return**。

那沒回傳值只是單純要跑函式內的程式呢?我們就會利用上面出現過的**void**來宣告資料型態。

我們舉一個例子，今天我們寫一個a+b的函式，也就是傳入a與b，並回傳a+b。

```cpp=
#include<iostream>
using namespace std;

int add(int a, int b);    //這是宣告

int main()
{
    int a, b, c;
    scanf("%d %d", &a, &b);
    c = add(a, b);
    printf("%d", c);
    
    return 0;
}

int add(int a, int b)
{
    return a+b;
}

/*輸入=
1 2
輸出=
3
*/
```

是的，我們必須再使用一個變數去接收函式所回傳的值，也就是我們的 **c**。

如果函式中參數名字與主函式不同也沒關係，不過在函式內運算的話還是得利用函式所宣告的參數。

小提醒 : **return**後，後面的程式都不會執行喔!

那假設 ```void``` 函式若不回傳，則傳進去的值會改變嗎?

```cpp=
#include<iostream>
using namespace std;

void add(int a, int b, int c);

int main()
{
    int a, b, c = 0;
    scanf("%d %d", &a, &b);
    add(a, b, c);
    printf("%d", c);
}

void add(int a, int b, int c)
{
    c = a + b;
}

/*
輸入 : 1 2
輸出 : 0
*/
```

這代表即使把```C```傳進去函式內了，但```void```不會回傳，所以```C```的值在函式內改變了，在主函式也不會改變。


