上一章
利用先前學到的概念,我們已經有能力可以讓程式跟人互動了!
不過,這樣似乎還缺了甚麼?
我們的程式目前好像只能模仿我們的輸入
如果我們的程式除了記憶力之外,還可以擁有強大的運算能力,把計算結果輸出給我們,那該有多好啊~
這樣,就可以真正的利用程式來幫助我們計算了!
要讓我們的程式開竅,我們可以使用「運算子 (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)
所以int不是取高斯函數喔==
回覆刪除不是哦,是直接省略小數部分
刪除您可以用以下程式碼來驗證這件事:
#include
int main()
{
float a=-1.6;
int b=a;
printf("%d\n",b);
return 0;
}
輸出會是「-1」而不是「-2」哦
感謝您的發問~^_^
Oops...Sorry程式碼爛掉了
刪除補上
#include<cstdio>
int main()
{
float a=-1.6;
int b=a;
printf("%d\n",b);
return 0;
}
不好意思ㄝ我從這裡看不懂 所以,剩下的「31個位元」所能表示的數字範圍就是「0∼231−1」了
回覆刪除也就是「0~2147483647」
因此
int的最小值是「-2147483648」(「負數的0」和「正數的0」是相同的,因此為了避免浪費,電腦會把「負數的0」當作「-2147483648」) (註3)
int的最大值是「2147483647」
因此,如果int的計算結果超出了「-2147483648~2147483647」的範圍,電腦就會因為撥出來給int變數的記憶體不夠而算錯喔~
哈囉,感謝您的提問~
刪除每個位元有2種情況 (0或1),因此31個位元可以有2^31種組合,可以用來表示 0~2^31-1 (正數) 或 -1~-2^31 (負數)
這段可能需要一些排列組合的知識才會比較好懂哦~
已更新本文章,您可以再看一次試試看能不能看懂哦~
刪除想請問一下
回覆刪除我要輸入兩個數字並輸出兩數的乘積
這樣為甚麼錯呢??
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
double num1, num2, product;
product = num1 * num2;
cout << "Please enter two floating-point numbers: ";
cin >> num1 >> num2;
cout << "\nThe product is " << product;
}
請先設定好num1、num2的數值才能用它們算出正確的結果哦~
刪除以下才是正確的寫法:
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
double num1, num2, product;
cout << "Please enter two floating-point numbers: ";
cin >> num1 >> num2;
product = num1 * num2;
cout << "\nThe product is " << product;
}
請問如以double來寫如下結果出現1.666667是否正常?
回覆刪除如我想以1.666666666出現結果該如何去改呢?
double a=5.0,b=3.0;
scanf("%1f",&a,&b);
printf("%f\n",a/b);
請參考「13 - 4. 指定輸出格式 」這篇~要多少小數位數自己設定!XD
刪除不過,double還是有其精確度上限,因此某個小數位數之後就不是準確的值了
您好,我打開匯出EXE檔
回覆刪除的確有將我運算的值算出來,但視窗都是一開起就閃退
即便是複製您的程式碼也是如此
請問問題是出在哪?
可能是因為您的Dev-C++不是最新版本
刪除請到這個網址下載安裝最新版Dev-C++~
我想問那個文章裡的溢位
回覆刪除我覺得我有點聽不懂但是我使用Python去算他卻不會這樣耶~
python沒有溢位的問題哦!因為python內建的int實際上是大數(Big Integer)
刪除附帶的作用是python實際上執行的速度會比c++要慢上很~~~多~~~XDD,畢竟電腦不擅長處理無限的東西,而python就有點違反的電腦的本質
如果真的需要,在c++大數也可以自行實作哦!