暨上篇介紹完 陣列 (Array) 之後,不知道大家有沒有更熟悉陣列的概念了呢!
相信大家一定曾經遇到過這樣的問題,就是當要宣告一個變數的時候,突然發現那個變數需要有好多的屬性,但是每一種屬性的資料型別 (Data Type) 可能都不一樣,有int、char…,那這個時候我們該怎麼辦?
別擔心,接下來, Hani 就是要帶大家來瞭解一下C語言當中非常實用的自訂型別方法 — 結構 (Struct)
準備好了嗎? 那就讓我們開始吧!
結構 (Struct) 的概念?
還記得嗎?我們上次說到
陣列是一個用來儲存『相同資料型態』元素的集合。
而結構的主要用途是
將各種不同資料型態的變數集合起來,變成一個新的資料型態。
什麼意思?還是有點霧煞煞的對吧,來看看下面這段程式碼!
struct employee {
char name[10];
int age;
float salary;
char phone_number[10];
};
說明:上面這段程式碼中,我們利用C語言中的關鍵字 struct 來宣告了一個名為 employee 的結構,當中包含了4個不同的屬性,分別是
- name (字元陣列)
- age (整數變數)
- salary (單精度浮點數變數)
- phone_number (字元陣列)
這樣我們就成功定義出了一個新的資料型態 — 『employee』
如何宣告結構變數?
Name_Of_Structure Name_Of_Variable;
Name_Of_Structure : 這邊就是我們剛剛利用 struct 定義出來的自訂型態。
Name_Of_Variable : 想取的名稱。
下面這段程式碼就是實際的宣告方式!
struct employee Dennis, Paige;
又或是還有另外一種宣告方式,將變數直接宣告在 struct 之後
struct employee {
char name[10];
int age;
float salary;
char phone_number[10];
} Dennis, Paige;
結構變數要初始化嗎?該怎麼做?
記得,一定要養成初始化的好習慣!
那初始化該怎麼做呢?方法有三種:
方法1:宣告結構變數時,直接將值assign進去
struct employee Dennis = {
"Dennis",
24,
78000,
"0923473923"
};
***一定要記得用逗號將各個屬性隔開哦!***
方法2:直接用屬性的名稱來指定,這樣就可以不用按照結構宣告時的順序
struct employee Dennis = {
.phone_number = "0923473923",
.name = "Dennis",
.age = 24,
.salary = 78000
};
方法3:在自定義結構的時候,同時宣告結構變數並初始化
struct employee {
char name[10];
int age;
float salary;
char phone_number[10];
} Dennis = {"Dennis", 24, 78000, "0923473923"};
*** 記得!結尾一定要加上分號! ***
如何存取 (access) 和指定 (assign) 結構當中的值?
利用 .(點)來存取和指定結構內的值。
什麼意思呢?下面讓我們來指定值到 Dennis 這個結構變數!
strcpy(Dennis.name,"Dennis");
Dennis.age = 24;
Dennis.salary = 78000;
strcpy(Dennis.phone_number,"0923473923");
p.s. 不要真的打電話過來喔~我是不會接的!
陣列可以用來儲存結構嗎?
當然可以!
相信大家還沒有忘記陣列的定義吧~忘記的話記得來這裡複習一下!
對於陣列來說,只要儲存的是同一個資料型別的變數,那就沒有問題,而結構正是我們自定義的一個新的資料型別,所以利用這個結構宣告的陣列中儲存的就是這個結構型別的變數。
不知道大家看到這裡是不是已經知道怎麼宣告結構陣列了呢?
struct employee part_time[20], full_time[20];
上面這段程式碼,我們宣告了兩個結構陣列,分別是 part_time 和 full_time 的 employee,陣列長度都是 20。
結構可以作為函數 (function) 的參數傳遞嗎?
當然也可以!
利用結構宣告的變數,也是一個變數,所以也是可以直接拿來當作函式的參數傳遞出去的。
舉例來說:
#include <stdio.h>
struct employee {
char name[10];
int age;
float salary;
char phone_number[10];
};
void transfer_employee(employee trans_employee) {
trans_employee.salary = 82000;
printf("%f\n",transfer_employee.salary)
}
int main() {
struct employee Dennis = {
"Dennis",
24,
78000,
"0923473923"
};
transfer_employee(Dennis);
printf("%f\n",Dennis.salary);
return 0;
}
上面這段程式碼中,我們將 Dennis 當作 transfer_employee 這個 function 的參數傳過去,然後修改了其中的 salary 屬性,接下來考考大家,執行結果會是怎麼樣呢!
答案揭曉:
82000
78000
因為在傳送 Dennis 這個參數的時候,OS 會額外複製一個 Dennis 傳送過去,因此我們在 transfer_employee 中修改到的是全新的 Dennis,而在 main function 中的才是原來的 Dennis,所以有兩個不一樣的 Dennis,這樣懂了嗎!
p.s 這樣的傳送方式稱為 call by value。
結構當中可以再放進結構嗎?
也是可以的!
有些時候某些屬性本身也是一個結構,而這樣的情況就必須在結構中再嵌入結構。
來看看這段程式碼!
struct date {
int month;
int day;
int year;
};
struct human {
char name[10];
int age;
struct date birthDate;
};
由於日期本身還會額外包含年份、月份,所以上面的 birthDate 變數就會是用 date 這個結構來宣告。
補充 – typedef 用法
看到這裡,不知道大家有沒有發現,我們上面定義完結構之後要宣告結構變數時,前面都還是要加上 struct 關鍵字來宣告,非常麻煩,那麼有沒有什麼方法呢?
利用 typedef 來定義別名。
來看看這個例子!
typedef struct employee Emp;
struct employee {
char name[10];
int age;
float salary;
char phone_number[10];
};
經過 typedef 的宣告之後,我們就幫 struct employee 創造了一個新的別名 – Emp
所以接下來我們要宣告的時候就可以不用再寫 strcut employee 啦!
Emp Dennis = {
"Dennis",
24,
78000,
"0923473923"
};
總結
以上就是7段關於結構 (Struct) 的程式碼:
- 結構 (Struct) 的概念?
- 如何宣告結構變數?
- 結構變數要初始化嗎?該怎麼做?
- 如何存取 (access) 和指定 (assign) 結構當中的值?
- 陣列可以用來儲存結構嗎?
- 結構可以作為函數 (function) 的參數傳遞嗎?
- 結構當中可以再放進結構嗎?
- 補充 – typedef 用法
希望看完之後,大家就可以開始活用 Struct 來寫程式了!
對文章有任何問題的話,都非常歡迎下面留言讓我知道哦!
By Hani
用很有趣的方式介紹,整理的蠻好的,然後電話那邊有點逗哈哈哈
哈哈哈,希望對妳有幫助!
感謝分享~雖然對初學者的我還很難
但我會繼續努力
慢慢來,付出的努力一定不會白費!
解釋得很容易理解,非常感謝這麼用心的介紹,傳址傳值剛開始很容易弄錯
之後會寫一篇文章專門介紹call by reference跟call by value,謝謝你的回饋!
大學不小心這科就被當掉了!!
哈哈哈,看來我應該早點架設Hani CS Daily的!
這對初學者的我來說還有點難理解
但是版主整理的非常平易近人!
先收藏起來,等我更熟悉時再回來看一次!!
謝謝版主細心分享。
不客氣!
歡迎隨時回來看看!
文章看下來覺得很輕鬆好懂,對初學者的我來說,開始有一點點可以理解,謝謝分享!
有空可以再多回來看看喔!
版主介紹的很詳細很容易理解
對於初學者的我來說有很大的幫助
謝謝版主分享
不客氣,可以幫我分享給需要的人哦!
好久沒碰程式語言了,看完版主教學,馬上就想起來80%了,謝謝版大
水!這樣就對了啦!!!
謝謝站長分享的教學文,好容易理解哦
簡短的重點提醒,對我這種有閱讀障礙的人來說,真是太棒了!
簡短的重點才記得起來啊~記憶體是非常重要的,一定要省著點用!
整理得很清楚!另外也推薦版主可以看看目錄的這項外掛https://www.johntool.com/wordpress-table-of-contents/
就會自動幫你整理好在最前面了!
是阿璋的文章耶!哈哈哈,沒問題,我馬上去看看!
感謝版主詳細的整理分享,直接記重點~
讚!忘記隨時可以回來看看喔!
對於初學程式語言的人來說,介紹的真的是非常平易近人,馬上手刀加到我的最愛,期待版主更多的教學文章
謝謝啦~我會繼續努力讓大家可以輕鬆入門這些概念!
講解的好仔細!雖然我對這方面沒研究,但剛好身邊朋友有在研究,會幫版主分享!感謝版主分享~
謝謝你幫我分享!
感謝分享~對初學者的我來說太難,還是交給專業的人來吧
ok的!如果身邊有需要的人也可以分享給他們看看哦!
步驟講的很仔細呢
自己也是學程式的苦手
之前學到有點想放棄XD
謝謝版主的解說~
每個領域都有每個領域的難關,加油!
好專業的文章XD 本來對這方面完全是零,看完好像覺得有0.1!哈哈謝謝分享
居然只有0.1XDDD~
常常覺得程式碼是很複雜的事情,不過看完您的文章又感覺並非那麼複雜,大概關鍵在於沒有人指點吧~
這也是其中一環,但是概念真的不複雜,只是看起來讓人害怕而已,所以我致力於把概念講解的簡單,希望能讓大家都更容易理解程式!