好比一個女僕被教導打掃客廳,每次就是打掃客廳,沒法指定他打掃房間!這太糟了不是?
怎麼讓它聽話好呢~我們要它聽話,當然是希望傳達訊息給它,希望它記住並因應做出回應對吧?
否則聽過就忘的話,跟沒講過有什麼差別呢~
所以,我們必須先賦予它「記憶」的能力!文字太複雜了,實數也太複雜了,先從整數開始!
先讓它能夠記憶兩個整數,加上這行:
int a, b;
最喜歡分屍講解啦!所以同樣地,我們也來拆解一下:
int <== 表示我們要賦予它「記憶」的能力,類型是「整數」。
a <== 被賦予的「記憶」的「代號」
, <== 分隔用
b <== 另一個被賦予的「記憶」的「代號」
; <== 指令結束
所以現在可以記憶兩個「整數」,分別記在代號a和代號b裡。
日後提到a就代表記在a的整數,提到b就代表記在b的整數。
我們稱a和b為「變數」,用來記憶資訊,並且記憶可以被改變。一個變數只能記一個東西。
因此,賦予記憶能力這件事,正式名稱為「宣告變數」。
每一份「記憶」都像收在一個櫃子一樣,需要相對應的「鑰匙(上述的代號)」去打開它,a和b就是鑰匙。
就像你要回想妹妹的手機號碼,會用「妹妹的手機號碼」作為鑰匙,打開相對應的櫃子,取出這個號碼,像是0987654321。哪天他換號碼並告訴你,像是0912345678,你就會把新號碼存進同一個櫃子。現在再打開這櫃子就只會是0912345678,原本的就不見啦!一個櫃子只會有一份記憶~
若你找不到這櫃子,可能是你妹妹沒有手機,或者你根本就沒有妹妹,所以沒有「宣告」這樣的「變數」。
有了記憶,接下來是讓程式聽話的時候啦。與輸出相同,需要依靠呼叫小妖精協助。
加入下列這行:
scanf("%d", &a);
這行會讓程式執行時,等待使用者輸入一個整數,並將這個整數存在變數a裡面。
使用者可以在執行時跳出的小黑窗上輸入。這指令會等候使用者輸入完才會結束,並繼續執行後面的指令。
讓我們拆解一下:
scanf <== 等待使用者輸入
( <== 在小括號中把細節交代得更清楚
"%d" <== 一段內含%d的文字。%d是一種約定的暗號,意思是「一個整數」
, <== 分隔要交代的不同細節
&a <== 對應暗號%d的出現而附加的訊息,告訴它%d讀入的整數必須存到a這個櫃子
)
;
同樣的,%d這個暗號,也是printf的約定暗號之一。
我們總不會只希望輸出固定的文字,有時也希望是數字等等,比如說告訴使用者,主角還有多少的HP之類!
但是文字是寫死的,沒法自由更動。所以printf就和我們約定了一個暗號,也就是%d。
只要在文字中看到暗號%d出現,就代表這個地方要顯示的,是一個整數,而不是%和d這兩個字。
printf("now your hp is %d\n", 70);
同時,出現%d我們就必須附加額外訊息。因為%d只告訴printf我們希望將%d給替換成一個整數,卻沒告訴它要替換成什麼!今天叫你去市場買條魚,可你不知道要買什麼魚!看起來不都長得一樣嗎?亂買回去八成被罵,printf也不想被罵,所以他會問得很清楚很仔細!
在此,我們就告訴它,想要輸出的整數是: 70。執行結果就會是:
now your hp is 70
完美!好,現在我們來進行練習:
等待使用者輸入一個數字,並告知所輸入的數字為何
這題目相當單純,但是不久後我們會看到它的應用,用來做個簡單的小遊戲!
首先分析一下,我們的程式要怎麼解這道題。
第一步,我們需要能讓使用者輸入一個數字。
第二步,我們需要能告訴使用者一個數字。
所以很顯然地,我們可以這樣寫:
#include <stdio.h>
int main()
{
scanf("%d", ); <== 輸入一個整數!
printf("your input is: %d\n", ); <== 輸出一個整數!
scanf(" "); <== 加上這個暫時以便觀看結果
return 0;
}
但是問題來了。只說輸入一個整數,根本不知道要記在哪!
只說輸出一個整數,但根本不知道要輸出的整數長什麼樣!
我們必須先讓程式能夠記憶輸入的數字。
#include <stdio.h>
int main()
{
scanf("%d", &num); <== 輸入一個整數!塞到num去
int num; <== 弄出一個變數來記憶輸入的數
printf("your input is: %d", &num); <== 輸出一個整數!同時告知該整數是num
scanf(" ");
return 0;
}
看起來該有的都有了,但是!這些指令可是按照順序,一條一條執行的喔!
所以不能先上車後補票啦!輸入時num都還沒出生呢,這怎麼可以!先後順序很重要的。
#include <stdio.h>
int main()
{
int num; <== 先弄出一個變數來記憶輸入的數
scanf("%d", &num); <== 輸入一個整數!塞到num去
printf("your input is: %d\n", &num); <== 輸出一個整數!同時告知該整數是num
scanf(" ");
return 0;
}
這就對了嘛!
好,大功告成啦!立馬F9戳下去試試,隨便輸入個整數看看…
5
your input is: 2293532
WTF!?輸入5,怎麼跑出奇怪的數字!?不信邪重新編譯執行,還跑出不一樣的數字!
哈,其實問題出在printf的num不可以加&啦!
啊?可是scanf不是加了嗎,怎麼不是scanf錯了!不然都拿掉看看…
結果還是跑出怪怪的數字,而且有時還會直接當掉!怎麼這樣…
這時我們需要了解一下&的意思。
一般在指令中出現變數名稱,像這裡是num,通常代表是num目前所儲存的內容。
以前面的講法是以num為鑰匙打開的櫃子,裡面存放的東西。
假如現在有個變數「妹妹的手機號碼」存著0987654321,現在你要用scanf讀入妹妹新的手機號碼,然後存在「妹妹的手機號碼」裡。
int sis_phone; <== 妹妹的手機號碼
scanf("%d", sis_phone);
於是你告訴scanf要儲存的位置是0987654321,scanf感到困惑!
第一我從號碼猜不到你想存在哪,難道我要一格一格翻嗎?
第二萬一你「上次打的號碼」和「女朋友的號碼」這兩個記憶也都是0987654321那麻煩大啦,誰猜得到要存哪邊!?
一個位置只存一份內容,但不同位置可能存在相同內容!
所以我們用&來取得存放位置。加上&表示變數位置,不加表示變數目前儲存的內容。
也就是說,在程式碼中看到
sis_phone => 0987654321 (存放的內容)
&sis_phone => 「妹妹的手機號碼」 (存放的位置)
應該告訴scanf後者才對!
這下就了解啦!同理,printf會輸出你傳給它的整數,而你把「妹妹的手機號碼」(位置)傳給它,它就把「妹妹的手機號碼」這個櫃子的「位置」給當整數輸出了,看起來當然很奇怪啦!
約定要告訴printf的是「數字」的話,就不該告訴他「去哪裡找」,他只會把「位置」當成是「數字」看待!
當別人問你妹妺的手機號碼,你也不會跟他說我記在腦中的XXXXXX位置,要他切開你大腦挖出來嗎?直接告訴他碼號是0987654321吧!
在了解這差別後,就知道什麼時候加&,什麼時候不用加啦~
因此,修改程式碼為
#include <stdio.h>
int main()
{
int num;
scanf("%d", &num); <== 告知儲存位置「妹妹的手機號碼」而非號碼本身
printf("your input is: %d\n", num); <== 告知號碼本身而非位置
scanf(" ");
return 0;
}
總之先F9編譯執行看看再說!
結果正確啦!太開心了!
那麼最後做個小練習吧?
讓使用者輸入兩個整數,之後以和輸入相反的順序,輸出這兩個整數。
比如說使用者輸入50 100這兩個數,你就要輸出100 50,數字一樣但順序要相反。
輸入30 20就要能輸出20 30才行!
輸入30 20就要能輸出20 30才行!
挑戰看看吧!若成功,應該就能順利掌握輸入的資訊都跑哪去啦!
小提示: 一個蘿蔔一個坑,兩個蘿蔔要幾個坑?
同一坑內,後到的會把先到的趕走喔!被趕走的無家可歸就只能自盡了喔!
小提示: 一個蘿蔔一個坑,兩個蘿蔔要幾個坑?
同一坑內,後到的會把先到的趕走喔!被趕走的無家可歸就只能自盡了喔!
沒有留言:
張貼留言