主人今天給了小希 200 塊,
小希好開心!收在哪兒好呢?
袖子嗎?裙底嗎?長襪嗎?
還是胸口──

咦?主人今天忘了帶錢嗎?
沒關係喔!小希請客吧~
主人的 80,小希的 64,
總共是 144 呢。給。

很快地,在第一幕之後。
我們開始有機會讓使魔自盡程式當掉了。

如果不是一直複製貼上,
相信有人經歷過了。
問題多半會出在 scanf() 的 & 上面。

為什麼 scanf() 需要加 &
為什麼 printf() 卻不需要?

通常忘了加 & 就很容易當掉,
或者出現非預期的結果。

我們來談談這件事。
回顧一下第一幕的重點:

當使魔請求主人輸入一個整數時
必須指定一個記憶格儲存
沒地方放的東西,就會隨風而去,
再也找不回來。

當使魔表達的文字列中,
有暗號指定要置換為一個整數時,
必須指定我們所希望的整數
否則使魔不會知道我們想置換成什麼數字。

scanf() 需要 『你想儲存的位置在哪裡』
	=> 地址
printf() 需要 『你想傳達的數字是什麼』
	=> 數值

假設我們現在有個記憶:

int power;

每個記憶都有它的實際儲存地址
以及它在那地址中儲存的數值

但光是寫出名字 power 不可能同時表達地址和數值。

我們必須避免一種寫法,有兩種或多種可能的解讀。
而『數值』被使用的機會,遠比『地址』高上太多。

只寫出名字 power 的時候,作為數值解讀。
作為地址解讀,則寫作 &power。

雖然聰明的你可能早就發現了:

只知道數值,無法逆推地址。
但若知道地址,就能知道數值。

那麼,問題來了:
為什麼 printf 不使用地址呢?

讓我們考慮以下狀況:

最近主人似乎有個煩惱。
期待已久的遊戲,還有數日就要發售。
可是主人手上的錢似乎不夠。

小希想幫助主人,所以必須知道還缺多少錢。
小希會從主人那問來整數 n 代表手上有多少錢,
以及整數 m 代表新遊戲的價格。

小希想要知道還缺多少錢。

雖然看起來複雜了些,
實際整理一下會發現其實是差不多的:

  1. 先有記憶(兩格)
  2. 再請示主人(兩次)
  3. 最後告知結果

除了需要更多的記憶外,
主要差別在於我們要的結果是:差多少。
也就是新遊戲售價和手上錢的差。

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main()
{
	int owned, game_price;
	scanf("%d%d", &owned, &game_price);
	printf("Master needs %d more money!\n", game_price - owned);
    return 0;
}

這時,printf() 採用數值的好處就相當明顯了。
它可以接受用運算式來代表一個數值。
game_price - owned 原本不存在於任何儲存空間 (註1),
是在執行到的當下,才開始計算的數值。

printf() 選擇接受數值,
不是沒有道理的。

另外,同類型的記憶,
可以用逗號隔開,一次宣告多個。

scanf() 和 printf() 都可以夾帶多個 %d;
一個蘿蔔一個坑。
若有兩個 %d,就要給兩個地址或數值。
有三個就得給足三個。
一樣使用逗號分隔。

基於先來後到的原則,
第一個 %d 會對到第一個地址或數值,
第二個 %d 會對到第二個地址或數值,
依此類推。

回到前面提及的,
為什麼忘了加 & 可能導致使魔自盡程式當掉呢?

如果說是把數值當地址傳入,
那應該是一定當掉,而不只是可能當掉吧?

因為電腦是用整數作為地址的。

程式執行過程中所有東西,
包括記憶、甚至程式碼本身,
都是放在記憶體中的。

由於都在記憶體中,
就像全世界都在同一條街道上,
地址就只需要門牌號碼,不需要街道名稱。

但我們給的值,不一定是系統配給我們使用的『記憶』的地址。

很可能是系統用的,
或者其它程式用的,
不一定是分配給我們可愛的使魔用的區段。

而我們可愛的使魔,
就可能因任務要把數字記入這些禁區,
卻又沒有足夠的力量與權限,
在了解到這任務不可能達成的那一刻,

只能選擇以死謝罪。

這些悲劇畢竟是身為主人的我們,
在寫下不適當的指令時導致的。
希望各位也能考慮使魔們愚忠的末路,
在編寫咒文時能更謹慎、更小心一些。

那麼,最後來捉弄一下可愛的小希,
看看他困擾時的可愛反應吧!

由主人給予兩個整數 a 和 b,
小希必須將這兩個數字,
按照主人給的順序,反過來回答!
也就是依 b → a 的順序回答。

試試看你能多快讓小希順利照你的意思行動吧!

  • *註1

    計算的當下,還是會有暫時的儲存空間。

    任何在當下存在的事物,
    都必定在當下佔有實際的空間。

    即使用完後就因為沒有保存的必要,
    馬上失去容身之處,再也無法拜訪。

    與其說它永遠不存在於任何一塊空間,
    不如說它只在運算當下擁有暫時的一席之地。
    在那之前、在那之後,都是不存在的。