---
# System prepended metadata

title: structure 結構
tags: [東華大學資管系, 資管經驗分享, 東華大學, 基本程式概念, 大一程設-下]

---

---
GA: G-RZYLL0RZGV
---

###### tags: `大一程設-下` `東華大學` `東華大學資管系` `基本程式概念` `資管經驗分享`

structure 結構
===

[TOC]

## 前言
structure 在 C/C++ 裡會被縮寫成 struct，但我們不討論在 C 裡面 struct 怎麼運作，我們只學 C++ 裡怎麼運作即可，而與他非常相像的東西叫做 class，接下來的幾篇筆記會帶例子讓大家了解這兩者的差異，以及講述物件導向的基本概念。

雖說大家一直說物件導向，但究竟甚麼是物件導向呢?

在真的討論什麼是物件之前，我想先跟大家回到一上我們在教資料型態做的事。

## 資料型態
還記得基本的資料型態有 `short`、`int`、`long`、`float`、`double`、`bool`、`char`，甚麼樣資料型態的變數存甚麼樣的資料，我想這大家並不陌生。
可能隨著我們的需求變多，會使用到 `陣列 []`、`vector`、`指標 *`、`函式 function`。

但大家試想一下，光靠這些東西就足夠開發大家平常使用的 APP、瀏覽的網頁、遊玩的遊戲了嗎?其實是完全不夠的，真正的開發需要用到的工具遠超大家的想像。

就單純以資料型態而言，光靠上述的東西完全不夠，有時候有些資料型態我們可能要<span style="color:red">**自訂**</span>出來。

這邊就不討論前端的使用者介面該怎麼辦，後端的資料庫要怎麼辦，我們就以開發這件事來看就好(其實就是寫程式啦!)

所以自訂我們所需要的資料型態(工具)，就是我們要學物件導向的最開始的原因。

> <span style="color:red">**而 structure 和 class 能夠讓我們根據需求自訂資料型態**</span>
> [name=Orange]

### 自訂資料型態?什麼意思?

整數、浮點數都是一種資料型態。
那假設我今天想要一個資料型態叫做人類，辦的到嗎?

> 辦的到，這個時候我們就是要定義一個 structure 或 class 叫做人類。
> [name=Orange]

那人類他一定有多種**特色**嘛，比方說每個人都有名字、身高、體重、性別、年齡、是否已婚、出生地、隸屬國家、月入薪水...等，非常多的特色。

除了特色，人能夠做的**行為/動作**還非常多，比方說跑步、跳舞、煮飯、說話、玩遊戲、教書、喝水...等，非常多事情。

而這些特色或是動作(行為)，我們都能夠自訂成一包資料型態，就叫做人類。

這就是 structure 跟 class 做的最核心的事情，<span style="color:red">**自訂資料型態**</span>。

上面的概念你懂了，我們馬上來自訂一個 `人類` 資料型態吧!

> 這邊有一句話希望大家開始刻在心裡，雖然你可能現在無法體會。
> <span style="color:red">**類別(結構)是物件的藍圖，根據藍圖將類別(結構)實體化成物件**</span>。
> 這句話可以說是剛開始學物件導向的核心。
> [name=各個大神們]

## 名詞解釋

* 上面所說的特色，其實就是我們常說的 -> **Data member(成員變數，亦稱屬性，以下簡稱 member)**
    * 其實就是把**變數**定義在自定義的資料型態內
* 上面所說的動作，就是我們常說的 -> **Member function(成員函式，亦稱方法)**
    * 其實就是把**函式**定義在自定義的資料型態內


## structure 語法認識

```cpp=
struct structure_name{
    member1;
    member2;
    memeber3;
    
    member_function1;
    member_function2;
    member_function3;
}; // <- 不要忘記這個分號!!!
```
<span style="color:red">在最後一個大括號後面，請記得要加上分號，這是固定語法請一定要遵守，後面的筆記會更深入談這個分號的功用。</span>

馬上來看個例子。
```cpp=
struct person{
    string name;            // member1
    int age;                // member2
    bool is_marriage;       // member3
    double weight;          // member4
    double height;          // member5
    
    // member_function1
    void run(){
        // 裡面會做跑步的事
    }
    // member_fuction2
    void eat(){
        //裡面會做吃的事
    }
    // member_function3
    string what_you_name(){
        return ("I am" + name);
    }
};
```

這樣你可能會問，這樣為甚麼叫做自訂一個資料型態呢?

假設今天我們需要一個<span style="color:red">**整數資料型態**</span>變數，我們會做`宣告`、`附值`的動作。
那如果我們今天需要一個<span style="color:red">**人類資料型態**</span>變數，也同樣要做`宣告`與`附值`的動作。

所以透過上方的例子，我們其實自定義了一個資料型態叫做 `person`。而我們都知道無論是需要變數、陣列、指標，都需要資料型態。像下面的例子。
```cpp=
int a = 5; //宣告並附值一個整數
person p1; // person 是我們的資料型態，p1 是我們的變數名稱
```

## 如何使用 struct?
不囉嗦直接看 CODE。
```cpp=
#include <iostream>
using namespace std;

struct person{
    string name;            // member1
    int age;                // member2
    bool is_marriage;       // member3
    double weight;          // member4
    double height;          // member5
    
    // member_function1
    void run(){
        // 裡面會做跑步的事
        cout << name << " is running..." << endl;
    }
    // member_fuction2
    void eat(){
        //裡面會做吃的事
        cout << name << " is eating..." << endl;
    }
    // member_function3
    string what_your_name(){
        return ("I am" + name);
    }
};

int main(){
    person p1;
    p1.name = "orange"; p1.age = 21; p1.is_marriage = false;
    p1.weight = 60; p1.height = 1.73;
    p1.what_your_name();
    p1.run();
    p1.eat();
    
    person p2;
    p2.name = "tiffany"; p2.age = 20; p2.is_marriage = false;
    p2.weight = 1.6; p2.height = 50;
    p2.what_your_name();
    p2.run();
    p2.eat();
    
    return 0;
}
```

在 main 可以看到我宣告了兩個 person ，一個叫做 p1，一個叫做 p2。
我想應該不難理解，他們就像 int、float、string 變數一樣，如果要使用就要宣告出來。

而對我們自定義資料型態的變數，當我們把它宣告出來的這個動作就叫做實體化。


## 實體化
<span style="color:red;font-size:20px">**類別(結構)是物件的藍圖，根據藍圖將類別(結構)實體化成物件**</span>。

在上例的 28 行跟 35 行，我們宣告了 p1 跟 p2 兩個 person 變數，這個動作就叫做把類別(結構)實體化成物件。

那為甚麼稱為類別(結構)藍圖呢?
<span style="color:red">**藍圖只是一個規格**</span>，只要是人類變數，他們都會有藍圖內的屬性跟方法，以上例而言，只要是人類，都會有名字、年紀、是否已婚、體重、身高這些屬性，跟跑、吃、回答名字三種方法。

所以藍圖是抽象的，你必須要根據藍圖把人實體化出來，才真的會有人。

> 以故事情境來說，如果今天要生產一個蛋糕，一定會有蛋糕的作法(藍圖)，大
> 家會遵照做法(藍圖)，把蛋糕給生產(實體化)出來。
> 希望帶個例子大家會比較好理解。
> [name=Orange]

### <span style="color:red">取用</span>屬性、<span style="color:red">取用</span>成員函式(方法) member function

實體化(宣告物件)沒問題之後，我們來說一下取用屬性跟方法。在上例的 29 ~ 33，36 ~ 40 行。
<span style="color:red">**每一個**</span>人類物件(變數)都有名字、年紀這些屬性或是跑、吃這些方法，而我們在程式碼的做法是實體化一個人之後加上 `.` 這個符號，還記得一上就說過 `.` 這個符號代表中文字 `的`。

所以
```
p1.name = "orange";        // p1 的名字屬性
p1.age = 21;               // p1 的年紀屬性
p1.is_marriage = false;    // p1 的是否已婚屬性
p1.weight = 1.73;          // p1 的體重
p1.height = 60;            // p1 的身高
p1.what_your_name();       // 呼叫 詢問 p1 的名字 方法(函式)
p1.run();                  // 呼叫 p1 跑步(函式)
p1.eat();                  // 呼叫 p1 吃東西 (函式)
```

跟上學期很相似的概念是甚麼呢?
一個字串都有詢問長度這個方法。
```
string s1 = "orange";
s1.length();    // 呼叫 s1 的長度方法(函式)
```
<span style="color:red">**每一個**</span>字串都有詢問長度這個方法(函式)

所以你有感同身受嗎，一個字串其實他是一個被實體化出來的物件，他隸屬於 string 這個類別(藍圖)，今天要使用字串，我們把它實體化成一個物件(s1)。

> 所以為什麼我們從未說過 string 是一個基礎資料型態，像 int 或 float
> 因為他是自定義資料型態。
> [name=Orange]

### 取用屬性
接著你應該有發現，屬性後都沒有括號，因為他只是一個值。像名字、體重、身高...等。
```
p1.name
p1.weight
```

所以千萬不要在不該加上括號的地方加上括號，要加括號代表他是一個函式(方法)。

### 取用(函式)方法
而取用類別(結構)的函式呢，就如同一上在教 function 一樣，同樣有可能有參數，或者沒有。而一般的呼叫 function 如下。
```
function_name(arguments)
```
而物件的函式(方法)就只是多了，隸屬於誰的這樣的動作。
```
p1.run()
p1.eat()
```

是誰要執行跑這件事，誰要執行吃這件事。

--- 
最基本的用法就講到這裡，更進階的就給後面的筆記吧!

## Reference
* [C++ Struct 教學](https://vinesmsuic.github.io/2020/01/16/c++-struct/#reference)
* [C 語言：結構（struct）自訂不同資料型態綁一起](https://kopu.chat/c-%e8%aa%9e%e8%a8%80%ef%bc%9a%e7%b5%90%e6%a7%8b%ef%bc%88struct%ef%bc%89%e8%87%aa%e8%a8%82%e4%b8%8d%e5%90%8c%e8%b3%87%e6%96%99%e5%9e%8b%e6%85%8b%e7%b6%81%e4%b8%80%e8%b5%b7/)
* [C++ class和struct的区别](http://c.biancheng.net/cpp/biancheng/view/2982.html)