--- 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)