創作內容

97 GP

[達人專欄] 跟著豬腳 C 起來:一次宣告一堆變數的方法

作者:解凍豬腳│2018-12-20 13:09:18│巴幣:1,293│人氣:6580
 
  前篇:跟著豬腳 C 起來:各式各樣的資料型態

  大家好。還記得上次豬腳跟大家示範了幾種內建的資料型態,對吧?這樣你應該對於「變數」如何運用跟規劃,稍微有了些概念。例如,我們想要儲存一個學生的性別、分數、存款、身高、體重,就可以如以下的方式來宣告。我們來複習一下:

    // 關於性別,我們可以用 1 代表男生、2 代表女生、3 代表其他……等等,隨你自由設定,只要別把規則設得太複雜,能方便使用即可
    short gender = 1;
    short score = 87;
    int money = 22000;
    float height = 172.4;
    float weight = 67.3;

  有了以上的宣告跟初始化,就可以儲存某個人的五項資料到變數裡,並且在之後有需要的時候操作它。例如今天他在路上撿到了 1000 元,並且存入了銀行,那我們就可以做:

    money += 1000;

  這樣的話,電腦就會把 1000 元加進原有的 22000,使得 money 這個變數的值成為 23000。

  然而,倘若今天情況變得不同——現場有 10 個人,存款皆為 0 元,而我們想要用變數來儲存這 10 個不同人的存款,怎麼辦?剛學過變數宣告的人,就會這麼做:

    int money1 = 0;
    int money2 = 0;
    int money3 = 0;
    int money4 = 0;
    int money5 = 0;
    int money6 = 0;
    int money7 = 0;
    int money8 = 0;
    int money9 = 0;
    int money10 = 0;

  這麼做的話,當然可以達到目的。但是,如果今天有 600 個人的資料需要儲存跟處理呢?我相信你不會希望花了整整 600 行的篇幅,就只為了宣告這堆變數。

  你可要知道,電腦本來就是被設計來處理大量資料的,不是嗎?所以,在大部分的程式語言當中,都有個很好用的功能,叫做陣列(array)。如何使用呢?我們只需要在宣告的時候使用中括號和想宣告的數量,就可以一次宣告很多個變數:

  int money[600];

  從這句應該不難看出就是宣告 600 個叫做 money 的變數。為了在這 600 個都叫做 money 的變數之間做出分別,所以系統對它們加上了編號。當然你可以把它想像成令電腦設置一個含有 600 個格子的置物櫃,並且將這個置物櫃取名為 money。



  請注意,在 C 語言(以及大部分的程式語言)當中,array 都是從 0 開始編號的。這是因為在 money 這個 array 裡面,後面的 599 個變數都是依序緊接著排在第一個的後面,畢竟電腦只要將記憶體的參照位置都以第一個為基準的話,就不需要耗費太多空間去一一記錄 600 個不同變數的記憶體位置。

  所以,我們只要用一句 int money[600]; 宣告完,就可以使用 money[0] ~ money[599] 這樣總共 600 個各自為一個 int 型態的變數(這樣每一個變數在 array 裡面稱為元素)。

  先前在介紹變數的時候,不曉得大家還記不記得,身為一個有良好習慣的工程師,如果宣告完變數,記得要把裡頭的數值初始化,例如:

    int count = 0;

  這件事情拿到了 array 上面也是同理,只是表達方法不同。我們如果想要把這 600 個元素統一設為 0 的話,應該在宣告的同時這麼做:

    int money[600] = {0};

  這樣一來,就可以確保宣告好的每個元素都是 0,而不會遇上殘值的問題了(也就是先前舉例過上一個使用廁所的人沒沖馬桶的情況)。

  如果我們想要為這 array 裡面的其中一個元素賦值或是運算,其實做法就跟一般的變數沒有什麼不同:

    money[22] = 4000;
    money[3] += 300;

  這麼做的話就是將 money 這個 array 裡的第 23 個元素設為 4000,第 4 個元素則是增加 300 進去。千萬別忘記了,陣列一律都是從 0 開始數。

  Array 就是這麼方便的東西。

  所以,將 array 搭配上次的 char,我們還可以這麼做:

    char name[32] = "UPK.painting";
    printf("Hello, my name is %s.", name);

  只要把很多個 char 組起來,就會成為一個字串(string)。現在其實許多程式語言都已經內建字串為一種資料型態,不需要刻意把 char 用陣列串起來,更不用設定字串長度的最大值就是了。

  當然陣列還有更進階的用法,例如二維陣列(陣列裡頭的每個元素都是一個陣列)、三維陣列(陣列裡頭的每個元素都是一個二維陣列),或者是把陣列搭配迴圈使用,都可以完美地把陣列存在的意義發揮得淋漓盡致。關於迴圈,我們會留到下次再說(當然你也可以先自己拿去問 Google)。

  補充:在其他程式語言裡不只 array,有的語言還另外內建 list、slice、map、hash table 等功能,這些東西同樣都是可以儲存多個變數,但因為使用方法及可以做到的事情不太一樣,因此都有各自的優缺點。因為 C 語言就只有內建最簡單的 array,所以就不多談了。

  學會了 array 的宣告及使用以後,我們可以利用這樣的方法,將 600 個學生的性別、分數、存款、身高、體重使用簡短的幾句儲存起來了:

    short gender[600] = {0};
    short score[600] = {0};
    int money[600] = {0};
    float height[600] = {0};
    float weight[600] = {0};

  這種情況下,我們就完成了 600 筆個資的宣告,只要使用 gender[27]、score[27]、money[27]、height[27]、weight[27] 就可以取得第 28 個人的資料。

  但這樣實在太不直觀了。明明每個人都會有這五種屬性,我卻得要輸入五次 600 來宣告它,這樣不是很奇怪嗎?如果今天想要改成 2000 筆,我要把好幾個 600 一個一個改成 2000,這樣也挺麻煩的。

  再說,我們在查詢分數的時候,也習慣說:「28 號學生的分數」,而不是「分數表上的第 28 筆資料」,不是嗎?

  所以說,既然是以「人別」來作為分類,我們就不應該以「屬性別」來宣告,這樣才比較符合我們人類平常習慣口頭上說的語言。

  於是,我們又可以用到 C 語言的一個功能了:結構(structure)。它有點像是剛才所提到 array 的變種,差別在 array 是用編號來指定元素,但 structure 則是使用成員(屬性)的名稱來指定,而且 structure 可以儲存很多種不同型態的資料。

  如此一來,每個宣告出來的 structure 變數都好像一個實體的物件一樣,就會讓人覺得真的好像在操作物品,而不是一堆雜亂無章、毫無結構可言的變數。

  舉個例子。如果我們今天班上有 50 名學生,我們想要記錄他們的姓名、性別、身高、體重、分數,那我就可以利用 struct 功能,先宣告好「一個 student 該有哪些屬性」,宣告的方法跟一般宣告變數的格式類似,只要使用資料型態和屬性名稱即可:

    struct student {
        char name[32];
        short gender;
        float height;
        float weight;
        short score;
    }

  放在 main 裡面就可以了(你想放在 main 外面也沒問題,這會牽涉到這個結構可以被誰使用,等到之後介紹「函數」,就可以放在一起講了)。

  請注意,以上這段程式碼只是預先向電腦定義好型態,並沒有實際要求電腦挪出記憶體、宣告成可以存取的變數。

  直到下面這步,才是實際宣告變數:

    struct student myStudents[50] = {0};

  這就跟一般宣告陣列沒有什麼不同,我們只不過是把原來該填入資料型態的地方換成了 struct student 而已。



  只看文字的話好像有點複雜,其實只是像上圖這樣,先告訴電腦一個 student 該有什麼,然後再一次宣告很多個 student,如此而已。

  我們就得到了 50 筆已經初始化完的學生資料變數。那麼該如何取值呢?我們可以使用半形的「.」來連接,在這裡你可以暫時把它口語化理解成「的」,例如:

    myStudents[3].score = 70;

  這樣就可以令「第 4 個學生『的』分數」為 70 分了。

  使用 structure 的方便之處在於,倘若今天突然發現漏了東西,我們臨時想要補上記錄學生父母名字的欄位的話,就只需要修改 struct student { … } 這段,在裡面另外加上兩個變數即可:

    struct student {
        char name[32];
        char dadName[32];
        char momName[32];
        short gender;
        float height;
        float weight;
        short score;
    };

  最重要的是,定義好的 struct 可以重複使用,這樣如果有很多不同班級的學生資料需要被記錄,那我們就不需要一直複製貼上了,寫出來的程式碼就會簡單又乾淨。

  其實說到這裡,我們還沒有完全發揮 structure 跟 array 的特性,目前這篇的內容只能讓讀者知道宣告變數的時候應該要有策略地運用兩者,以免後患。

  下次,我會說明如何利用「迴圈」的技巧,令程式執行大量重複的類似工作,並且和今天所提到的陣列和結構搭配使用,只要把這些學會,你就已經完成基礎的一半囉!敬請期待。
 
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4232382
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:第一次踏入墳場就上手|從入門到入墳|從入門到放棄|C語言|程式設計|C|C++|寫程式|程式|回收業者

留言共 30 篇留言

死螞蟻司馬燚
阿是郭

12-20 13:11

雪之王女‧F‧巧可奈
你居然改暱稱了XD

12-20 13:24

我愛 ( I ) 黎明
優質豬腳(`・ω・´)b
吃我GP

我天賦差
多重迴圈加陣列直接死_(´ཀ`」 ∠)_

斯巴( | )拉稀~~~

12-20 13:24

夜貓Nightcats
剛好前幾天有教structure 現在再複習一次 蒸蚌

12-20 13:25

屁屁好乾爽
優質

12-20 13:25

未燃的鬼火
請問你是不是在做教材

12-20 13:28

解凍豬腳
不是喔~ 單純分享12-20 13:30
愛情馬卡龍
現代人不會程式碼會不會被當白ㄘ

12-20 13:49

單身狗英雄
c語言我忘光了

12-20 13:52

乃乃
帥 讚

12-20 13:53

雨夜猫/RainyNight
正好未來想讀資工系,感覺有幫助先訂閱了w

12-20 13:57

呆皮的同學
忘光了 都用物件

12-20 14:12

orz8787
剛打完
有看到c語言
頭好痛

12-20 14:20

佚名
C語言的精華在link list,link list 最重要。

12-20 14:37

魔物型態 海星
看得我痛苦

12-20 14:41

再生と破壊
U質好文

12-20 15:10

Router
推 好文

12-20 15:25

夜黑風高
推有心

12-20 15:42

我哪知
print ("幹你屁眼");

12-20 16:11

解凍豬腳
printf 啦幹12-20 16:13
中二И小屁孩
可以敎linklist嗎 做c++的做到起笑= =

12-20 16:27

恐龍化身DIO

12-20 16:29

阿辰
最近覺得文件的範本就像程式中的方法和一些資料結構,只要呼叫後,即節省不少時間。

總之本質就是提升效率。

12-20 18:42

更新的人格
用Dat5aTable來試試

12-20 23:48

別再打了我認錯就是了
天阿,我學C三個月居然沒聽過struct

12-21 12:44

解凍豬腳
如果要用旗標的 C 語言手冊來看:
unsigned, int, short, long, float, double
printf, scanf
if, else-if, else
switch, case
for, while, do-while
以及基本的運算,算是初學者得要碰的

再來 function, array, string, pointer, struct, enum 這些其實該算是相對比較進階的,所以如果剛開始還沒碰到 struct 都很正常

會先把 array 和 struct 拿來講,是因為我認為如果先讓初學者知道變數可以一次宣告很多個,這樣他們也才比較能理解說原來程式是這樣處理大量資料,同時也能早點養成某些宣告變數的時候的好習慣

例如 struct,這玩意有很多人都是明明知道有什麼用途,但都不會把它拿來用12-21 13:49
別再打了我認錯就是了
阿今天程式課終於有教structure了XD

12-22 13:43

李日立
物件用習慣後,就沒再用struct了

12-22 20:46

探子
class比較U

12-23 02:59

勇造是西行寺幽幽子
c c c8763

12-23 11:52

ㄇㄇ
跨某[e15]

12-24 19:09

暗月
我覺得可以稍微提一下 C++ 中的 struct 是可以省略的
像是 struct student myStudents[50] = {0}; 變成 student myStudents[50] = {0};

12-29 11:19

累了多喝水
U質

12-31 15:37

我要留言提醒:您尚未登入,請先登入再留言

97喜歡★johnny860726 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:FFK11 流水帳,暨 ... 後一篇:今年平安夜,我和らい單獨...

追蹤私訊切換新版閱覽

作品資料夾

------------------ (0)

豬腳生活 (1)
日常雜談、巴哈大小事 (193)
煞氣a國中生 (7)
高中生活日誌 (55)
大學生活日誌 (34)
冬令營回憶錄 (19)
也許藏有一些小祕密吧? (3)
各式各樣的開箱文 (11)
貓科動物時間 (15)

------------------ (0)

繪圖創作 (1)
電繪插圖、草稿 (199)
短篇漫畫、單幅標語 (61)
上課太無聊的手繪塗鴉 (8)
不知道該怎麼分類的綜合作品 (18)

文字創作 (1)
草莓兵的國軍紀實 (14)
我與らい的點點滴滴 (12)
那些榮耀的時刻與心跳加速的瞬間 (60)
有感而發的隨筆之作、無法分類的短文 (17)

------------------ (0)

語言學習 (1)
日語:天気がいいから (5)
粵語:唔好再淨係識講粗口喇 (6)
英語:Hey, you! (1)

程式設計及電腦網路 (1)
系列文:跟著豬腳 C 起來 (10)
系列文:論壇網站運作原理 (3)
Go(Golang) (11)
Ruby / RGSS (7)
Visual Basic (13)
JavaScript (1)
各種原理 (17)

思想:多思考一下,世界會更不一樣 (1)
網路經驗、社會觀察 (23)
檸檬庫 (21)

數學:我來拯救你的期中考了 (1)
各類基礎觀念 (5)
國中生也能懂的微積分 (9)
微分方程 (0)

小說:用筆鋒劃出新世界的入口 (1)

繪圖:我也想畫出私巴拉西的美圖 (10)

------------------ (0)

施工中 (22)

不堪回首的痕跡、雜物堆放 (31)

------------------ (0)

未分類 (1)

flys8028大家
有點色色取向的部落格 https://www.rocksugarcat.com/看更多我要大聲說昨天15:38


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】