内容簡介
1、第一部分第五課:簡易計算器
2、第一部分第六課預告:控制流程,随心所至
簡易計算器
上一課《【C 探索之旅】第一部分第四課:内存,變量和引用》中,我們已經學習了挺重要的内存的概念,變量的知識,對引用這個C 中常用的技術也有了初步的了解。
我 們在上一課開頭處用一個小小計算器的存儲技術引出内存的概念。其實我們的電腦兄也是一個計算器,隻不過高端大氣上檔次了很多,不然怎麼會被稱為 computer呢?英語中compute這個詞,正是《計算》的意思,而加上r就構成了名詞。computer就是“計算機”。(複論學好英語對編程的 幫助)。
所以,電腦不僅能儲存數據,還能進行很複雜的計算。
這一課我們就來聊聊計算。
請求用戶輸入信息
上一課中,我們學習了如何在控制台(console)中顯示變量的值。現在我們來做相反的事情:請求用戶為我們的程序提供輸入,以存儲到内存中。
如果以後你還會搞錯,不要跟别人說你是看謝什麼恩銘的文章學的。開個玩笑~
其他變量
當然了,上面提到的知識點,也可用于其他變量類型,例如:
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "您叫什麼?" << endl;
string userName("無名氏"); // 在内存中申請一個string類型的抽屜
cin >> userName; // 将用戶輸入的數據賦值給userName
cout << "PI的值是多少?" << endl;
double piValue(-1.); // 在内存中申請一個double類型的抽屜
cin >> piValue; // 将用戶輸入的數據賦值給piValue
cout << "您叫" << userName<< " ,您認為PI的值是" << piValue << endl;
return 0;
}
這次我想不需要給出什麼解釋了吧,自己運行此程序試試吧。
空格的問題
測試下上面的程序,是不是發現有點小問題?
假如我們如下運行:
您叫什麼?
Isaac Newton
PI的值是多少?
您叫Isaac,您認為PI的值是0
很奇怪是嗎?程序并沒有請求我們輸入PI的值,而是将PI的值改為了0。而且Newton不見了。哦,no,牛頓不見了,咋辦?小蘋果都不知道該往誰頭上掉了(小編你可以了...)
要說原因,這是空格的問題。當用戶按下回車時,程序會把用戶輸入在控制台的數據拷貝到内存的"抽屜"中,但是它會在第一個空格或回車符處停住。當用戶輸入的是數值時,并沒有問題,因為數值裡沒有空格。
但是當輸入的是字符串(string)時,可能會有空格。這樣,電腦就會在第一個單詞結尾處截斷,畢竟電腦也是挺呆萌的。這樣,在上例中,程序就會以為Newton是PI的值。
所以,我們須要截取所有一整行,而不是第一個單詞。那就要用到getline函數了。
我們将 cin >> userName 用getline函數替換,如下:
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "您叫什麼?" << endl;
string userName("無名氏"); // 在内存中申請一個string類型的抽屜
getline(cin, userName); // 将用戶輸入的整一行放入userName這個抽屜
cout << "PI的值是多少?" << endl;
double piValue(-1.); // 在内存中申請一個double類型的抽屜
cin >> piValue; // 将用戶輸入的數據賦值給piValue
cout << "您叫 " << userName<< " ,您認為PI的值是 " << piValue << endl;
return 0;
}
我們看到cin和userName還是在那裡,隻不過這次它們是作為getline的參數被使用了。
這次,運行程序後,就沒有問題了:
您叫什麼?
Isaac Newton
PI的值是多少?
3.14
您叫Isaac Newton, 您認為PI的值是3.14
首先請求PI的值
假如我麼首先使用cin >> 然後才使用getline呢?比如我們先請求用戶輸入PI的值,然後再請求用戶輸入名字。
你會發現程序又出問題了。程序并沒有向用戶請求輸入名字,而且輸出了随便什麼東西。
為了解決這個問題,我們須要在cin >>之後使用cin.ignore()
如下所示:
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "PI的值是多少?" << endl;
double piValue(-1.); // 在内存中申請一個double類型的抽屜
cin >> piValue; // 将用戶輸入的數據賦值給piValue
cin.ignore();
cout << "您叫什麼?" << endl;
string userName("無名氏"); // 在内存中申請一個string類型的抽屜
getline(cin, userName); // 将用戶輸入的整一行放入userName這個抽屜
cout << "您叫 " << userName<< " ,您認為PI的值是 " << piValue << endl;
return 0;
}
如果我們混合使用>>和getline,記得須要在cin >> 語句之後用cin.ignore()。這是一個規則,要記住。
改變變量的值
要進行運算,我們離不開變量。
首先,我們來看看如何改變變量的值吧。我們用=(等号)來進行數值的改變。假設我有一個int型的變量,我想要改變它的值,我首先寫這個int型變量的名稱,後面跟一個=号,再接新的數值。這就是變量的賦值。例如:
int number(0); // 在内存中申請一個抽屜,存放一個int類型變量,叫number,初始值為0
number = 5; // 将number的值改為5
我們也可以直接把一個變量的值賦給另一個變量:
int a(4), b(5); // 定義兩個變量
a = b; // 将變量b的值賦給a
上面兩句程序做了什麼呢?
首先,我們定義了兩個int變量,分别取名為a和b,也就是在内存中申請了兩個抽屜,初始值分别是4和5。
接着 a = b; 這句話将b的值賦給a,也就是用5代替了a原先的值4,如下圖所示:
#include <iostream>
using namespace std;
int main()
{
int a(4), b(5); // 定義兩個變量
cout << "a的值是 : " << a << ", b的值是 : " << b << endl;
cout << "賦值!" << endl;
a = b; // 将b的值賦給a
cout << "a的值是 : " << a << ", b的值是 : " << b << endl;
return 0;
}
運行,輸出:
a的值是 : 4, b的值是 : 5
賦值!
a的值是 : 5, b的值是 : 5
b的值并沒有改變,在賦值時,隻有等号左邊的值(稱為左值)會改變,等号右邊的值(右值)不會改變。這也不是說賦值運算中的這兩個變量是一樣的,隻是它們的值相等而已。
這是個好的開始,但是要稱得上一個最基本的計算器,我們還缺點什麼。是的,缺運算符。
最基礎的計算器
我們從最基本的運算符開始介紹,首先是加法運算符:
例如:
#include <iostream>
using namespace std;
int main()
{
int result(0), a(5), b(8);
result = a b;
cout << "5 8 = " << result<< endl;
return 0;
}
運行,輸出:
5 8 = 13
給出基礎的運算符的表:
運算 | 符号 | 用例 |
---|---|---|
加法 | result = a b; | |
減法 | - |
|
乘法 | * |
|
除法 | / |
|
取模 | % |
|
上表中前面四個運算符都好理解,但是最後一個"取模"是什麼意思呢?小學數學老師好像沒有教我啊。
取模就是除法運算的延伸。因為例如整數除法,我們有除不盡的時候,就會多出點"邊角料",這個邊角料就是模了,其實就是餘數。
因此,假如 13 / 4 等于 3 餘 1 (因為 3 乘以4,再加1等于13)
那麼1就是13 / 4 的模。
13 % 4 就等于1
有了這麼多運算符,我們就可以組合出複雜一些的運算啦,例如:
result = ((a b) * c ) - d;
常變量
這标題有點奇怪,不是嗎?
什麼叫常變量?要麼常量,要麼變量。
好吧,常變量就是不能改變的變量。
要聲明常變量,我們使用const關鍵字。const是constant的縮寫,表示"恒定的"。用const聲明的變量不可在之後的程序中被更改,不然程序運行會報錯。
隻 要适合用const的地方,都盡量用const。因為我們不但可以避免一些程序的錯誤(比如防止修改我們不想要其值改變的變量),而且const變量使得 編譯器更加有效率(因為const變量,編譯器之後就不會再去檢查它的值有沒有被改變了,不會再去重複取它的值,因為知道其值不能被改變)。
const用法如下:
string const password("wAsTZsaswQ"); // 密碼
double const pi(3.14); // PI的值
unsigned int const maxLifePoint(100); // 生命值的最大取值
下一課中,我們還會再聊const這個關鍵字。
縮略形式
程序員是很勤勞的,但是他們又是很會偷懶的。
會偷懶和偷懶不一樣,偷懶是貶義,會偷懶是褒義。會偷懶是指我們如果可以用更簡便的方法來完成某事,盡量不用原先複雜冗餘的形式。因為這樣可以節省開銷,降低程序複雜度。
我們就來看看幾個運算符的縮略形式吧。
在編程中,很多時候,我們需要将變量進行減1的運算,或者加1的運算。一般我們會這樣寫:
int a(4);
a = a 1; // 使a增加1
但是不覺得 a = a 1; 寫起來有點重複嗎?寫了兩次a诶,不能忍啊。
因此我們可以用自增運算符來完成同樣的操作。
自增運算
自增運算符是
也就是在變量名後跟
例如:
int a(4);
a ;
cout << "a的值是 : " << a << endl;
運行,輸出:
a的值是 : 5
自減運算
自減運算就是将變量的值減1啦。
int a(4);
a--;
之後a的值變為3。
自增運算符和自減運算符,有不同的擺放位置,不一定放在變量名後面,也可以放在變量名前面。作用有所不同。
a ; // 先使用a的值,再對a進行加1操作
a; // 先對a進行加1操作,再使用a的值
例如:
int b(0), a(2);
b = a ;
cout << "a的值是 : " << a << " , b的值是 : " << b << endl;
b = a;
cout << "a的值是 : " << a << " , b的值是 : " << b << endl;
運行,輸出:
a的值是 : 3 , b的值是 : 2
a的值是 : 4 , b的值是 : 4
為什麼呢?
因為第一次的時候,我們使用 b = a ; 是先将a的值賦給b,然後再對a進行加1操作。這句結束後,a的值變為3,b的值是2
接着,我們使用b = a; 是先将a的值加1,再将a的值賦給b。所以a的值首先變為4,再賦值給b,因此b的值為4。
要記憶也很容易,假如是a 的形式,由于變量名在左邊,所以先使用變量,再進行之後的 操作;假如是 a的形式,由于 符号在先,因此先進行自增操作,再使用變量。
其他運算符
其他運算符就是基礎運算符(加,減,乘,除,取模)與等号的結合使用了:
=, -=, *=, /= et %=
例如:
#include <iostream>
using namespace std;
int main()
{
double number(5.3);
number = 4.2; // number現在等于 9.5
number *= 2.; // number現在等于 19
number -= 1.; // number現在等于 18
number /= 3.; // number現在等于 6
return 0;
}
更多數學運算
也許你覺得不夠過瘾,畢竟我們隻是做了一些很基礎的運算。
那麼如果你要進行比如開平方根這樣的運算,該如何做呢?
我們需要引入一個C 的标準庫:數學庫,是cmath
#include <cmath>
在這個頭文件裡,包含了很多數學計算相關的函數。如下表(沒有列全):
函數名稱 | 符号 | 函數 | 用例 |
---|---|---|---|
平方根 | sqrtx | sqrt() | result = sqrt(x); |
正弦值 | sin(x) | sin() |
|
餘弦值 | cos(x) | cos() |
|
正切值 | tan(x) | tan() |
|
指數 | ex | exp() |
|
次方 | ab | pow() |
|
自然對數 | lnx | log() |
|
以10為底的對數 | log10x | log10() |
|
絕對值 | |x| | fabs() |
|
向下取整 | ⌊×⌋ | floor() |
|
向上取整 | ⌈×⌉ | ceil() |
|
總結
為了請求用戶輸入數據,我們使用如下格式:cin >> variable,之後用戶輸入的數據就儲存在variable變量中。
不要搞混了标準輸入和标準輸出運算符的方向:cin >> 是标準輸入,cout <<是标準輸出。
在C 中,我們可以做很多基本的運算:加,減,乘,除,等等。例如:result = a b
const變量是一旦定義就不能修改其值的變量(記得,不是常量)。我們用關鍵字const來聲明。
為了一個變量能夠進行加一運算,我們可以用自增運算符 ,variable 。還有一個自減運算符--,variable--,進行減一運算。
如果你要進行更複雜的數學運算,例如計算平方根,那麼需要引入C 的标準數學庫,就是cmath。使用方法: #include <cmath> 之後你就可以用标準數學庫中的各種函數了,例如計算平方根:result = sqrt(100);
第一部分第六課預告
今天的課就到這裡,一起加油吧!
下一課我們學習:控制流程,随心所至
ProgrammerLeague
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!