上一章
利用先前學到的概念,我們已經有能力可以讓程式跟人互動了!
不過,這樣似乎還缺了甚麼?
我們的程式目前好像只能模仿我們的輸入
如果我們的程式除了記憶力之外,還可以擁有強大的運算能力,把計算結果輸出給我們,那該有多好啊~
這樣,就可以真正的利用程式來幫助我們計算了!
要讓我們的程式開竅,我們可以使用「運算子 (Operator)」
運算子是甚麼呢?
千萬別被它的名稱嚇到了,其實「運算子」就只是「加減乘除」而已XD
比較需要注意的是,「乘法」的符號是「*」,「除法」的符號是「/」
(WTF原來這麼簡單?!)
還記的你在寫數學題目時會用到的算式嗎?
舉個例子:1+2的答案是?
你一定知道答案是3
信不信,電腦在學會「C++」之後 (電腦學會C++?請見第一章),也知道答案是3!
不信嗎?我們來做個小測試:
#include<cstdio> int main() { int a=1,b=2; printf("%d\n",a+b); return 0; }
不用說你也知道要做甚麼吧?
趕快在Dev-C++裡面把這份程式碼打出來,然後按下鍵盤上的「F11鍵」查看程式執行結果吧!
程式輸出3了! (可能有細心的讀者發現,我把Dev-C++的背景改成黑色了,這只是個人習慣,因為我覺得黑色背景比較好看XD) |
在打出這份程式碼的過程中,聰明的你可能會注意到
原本的寫法
int a,b;
變成了
int a=1,b=2;
意思就是,我們定義型別為int的兩個變數,a和b (不懂?複習一下第二章吧)
然後把a設定成1,b設定成2
這種「將剛被定義出來的變數設定數值」的動作
我們稱之為「初始化 (Initialization)」(這個看起來很難的字眼,其實真的就是這麼簡單XD)
如果你有使用過Windows XP作業系統,你可能在登入畫面看過這個字眼
沒錯,這時候「Windows XP」這個巨大的程式,正在設定它裡面每個變數的數值
這是Windows XP的登入畫面,有時候會顯示「正在初始化...」 |
程式輸出3了!電腦果然厲害!
那麼該來考考電腦了
現在,請你問問看電腦
2+3
567+789
273*7122
91/13
87411-24005
105-324
分別是多少呢?
答案是
2+3=5
567+789=1356
273*7122=1944306
91/13=7
87411-24005=63406
105-324=-219
你的電腦答對了嗎?
現在,請你嘗試問電腦更難、更刁鑽的問題
甚麼情況下電腦會答錯呢?
電腦真的有可能會算錯喔
舉兩個例子:
100000*100000
5/3
如果你覺得驚訝,代表你是個正常人
100000*100000的答案是「10000000000」
但是電腦卻回答了「1410065408」
5/3的答案是「1.6666666666......」
但是電腦卻回答了「1」
Why?
我們來回顧一下程式碼:
#include<cstdio> int main() { int a=100000,b=100000; printf("%d\n",a*b); return 0; }
以及
#include<cstdio> int main() { int a=5,b=3; printf("%d\n",a/b); return 0; }
可以發現,我們的程式是用兩個int去進行計算的
數學上,整數的加減乘法具有封閉性
也就是兩個整數相加、相減、相乘後的結果還是一個整數
程式上也一樣,「int」的運算也具有封閉性,不過封閉性更強了,連「除法」也具有封閉性!
事實上,你對兩個int進行任何運算,結果一定還是一個int!
int無法處理小數,所以「1.6666666666......」就捨去小數部分,變成了「1」,合情合理
(如果結果是「-1.6666666666......」,以int的型別儲存後就會變成「-1」) (註10)
至於「1410065408」,這就揭露了int的另外一個秘密了
事實上,你電腦的記憶體再怎麼多,還是有限的,因此不可能儲存很大很大的數字
對於int這種類型的變數,電腦會撥出大小為「32個位元」的記憶體去儲存它 (註1)
甚麼是位元?
就是0或1,電腦中最基本的儲存和運算單位
也就是說,int其實就是一個「最多32位數的二進位數字」
哪有?我們看到的int怎麼看都是一個十進位數字啊
那是因為電腦學會了C++,所以知道要怎麼把這個二進位數字轉換成十進位數字,輸出給我們看
那「負數」怎麼辦呢?
電腦學會了C++,很聰明的解決了這個問題
方法就是把32個位元的其中一個位元拿掉,這個位元就不用來表示二進位數字的其中一個位數了
電腦拿這個位元來表示這個數字的正負號
如果這個位元是0,表示這個數字是正數
如果這個位元是1,表示這個數字是負數
很聰明吧!
所以,剩下的「31個位元」所能表示的數字範圍就是「$0\sim 2^{31}-1$」(表示正數時) 或「$-2^{31}\sim -1$」(表示負數時) 了 (每個位元有2種情況 (0或1),因此31個位元可以有$2^{31}$種組合,這牽涉到一點數學排列組合的知識)
也就是「$0\sim 2147483647$」或「$-2147483648\sim -1$」(註3)
因此,int的最小值是「-2147483648」,最大值是「2147483647」
也因此,如果int的計算結果超出了「-2147483648~2147483647」的範圍,電腦就會因為撥出來給int變數的記憶體不夠而算錯喔~
這種情況,我們稱作「溢位 (Overflow)」,這是我們寫程式的人需要注意的,因為它會導致錯誤的計算結果
上面我們有提到,int無法處理小數,因此5/3的答案是「1」
不知聰明的你有沒有想到
那我們乾脆就用可以處理小數的「float」來計算就好啦!
廢話不多說,馬上來試試看!
#include<cstdio> int main() { float a=5,b=3; printf("%f\n",a/b); return 0; }
要注意的是,float也滿足加減乘除的封閉性,因此計算出來的東西也是一個float,要用「%f」來輸出,而不是int的「%d」
用「float」計算5/3的結果 |
等等,為甚麼最後一位是7?
剛剛有提到,電腦的記憶體是有限的,因此不可能儲存很大很大的數字,當然也不可能儲存很多很多的小數
float是用「科學記號」的方式儲存的,換句話說,「24005」會被當作「$2.4005*10^{4}$」來看待 (事實上不是如此,請見「註2」)
其中,「2.4005」和「4」是分開儲存的,和int一樣會被轉成二進位數字,儲存在電腦撥出來給它的記憶體中 (事實上不是如此,請見「註2」)
這兩個數字當然也有其範圍極限
還記得第二章提到的誤差問題嗎?
就是這樣來的喔~
綜合起來
float的範圍約落在「$-10^{38}\sim -10^{-38}$」、「0」、「$10^{-38}\sim 10^{38}$」
誤差約「0.00001% (也就是$10^{-7}$)」
這裡看不懂沒關係,你只要知道float有誤差就好 ^_^ (float非主流,見註6)
最後,再跟大家報告一個好消息
數學上,我們習慣「先乘除,後加減」
因此「$5\times 6+9\div 3$」的答案是「$5\times 6+9\div 3=(5\times 6)+(9\div 3)=30+3=33$」
而不是「$5\times 6+9\div 3=30+9\div 3=39\div 3=13$」喔
程式上,「先乘除,後加減」的規則也是成立的!
而且,還可以使用括號喔!
以下提供兩個例子,讓你深入了解C++程式的奧妙!
「先乘除,後加減」
#include<cstdio> int main() { int a=5,b=6,c=9,d=3; printf("%d\n",a*b+c/d); return 0; }
「先乘除,後加減」,因此程式輸出「33」 |
「有括號,要先算」
#include<cstdio> int main() { int a=5,b=6,c=9,d=3; printf("%d\n",a*(b+c)/d); return 0; }
「有括號,要先算」,因此程式輸出「25」 |
現在,換你了!
你玩出了甚麼東西呢?
下一章
感謝:pr3pony、李旺陽學長、WillyPillow
(版權所有 All copyright reserved)