
目標(biāo)
閱讀完這篇文章,你可能會(huì)了解到:
- 維X檸檬茶還不錯(cuò),智乃超可愛(ài).
- 讓程序相應(yīng)你的輸入,并輸出某些內(nèi)容
- 了解不同的變量類(lèi)型
-
如果邏輯結(jié)構(gòu) - zhx的冰紅茶做題法
- NOIP題目格式
算法基本結(jié)構(gòu)
當(dāng)在做題時(shí),基本步驟是什么:
- 讀題.不讀題做個(gè)P.
- 思考.不思考做個(gè)P.
- 回答.不回答做個(gè)P.
同樣的,一個(gè)程序至少要包括后2個(gè)過(guò)程.而通常,程序會(huì)包括3個(gè)過(guò)程.如果你理解了意思,接下來(lái),開(kāi)始吧.
例1:請(qǐng)問(wèn)今天你要來(lái)點(diǎn)...
抱歉,rabbit house是去不了了,不過(guò)今天集訓(xùn)隊(duì)可以去開(kāi)封菜.教練報(bào)銷(xiāo)哦.
開(kāi)封菜有很多吃的,比如牛肉漢堡,雞肉漢堡,薯?xiàng)l,可樂(lè),各種高熱量食品,對(duì)身體賊好(霧).現(xiàn)在,你已經(jīng)能寫(xiě)hello, world了,搞一個(gè)點(diǎn)餐程序應(yīng)該不難.
輸入
第一行一個(gè)N,表示有N個(gè)人點(diǎn)餐.
接下來(lái)N行,每行一個(gè)數(shù)字.其中
- 1 代表牛肉漢堡
- 2 代表雞肉漢堡
- 3 代表薯?xiàng)l
輸出
對(duì)于每一個(gè)人,你需要輸出單獨(dú)一行,共N行,每行為其點(diǎn)餐的中文名.
范圍
- 對(duì)于30%,0 < N < 10000
- 對(duì)于100%,0 < N < 1000000
啊哈,第一道題
"應(yīng)該不難"這種說(shuō)法,絕對(duì)是坑,請(qǐng)記住.
現(xiàn)在暫時(shí)簡(jiǎn)化這道題:假設(shè)集訓(xùn)隊(duì)的同學(xué)賊懶,他們打算讓教練把所有人的吃的一起帶回來(lái).
這樣點(diǎn)餐的就只有1個(gè)人了.(笑)
如同做別的題一樣,讀題是必須的.而且人們會(huì)發(fā)現(xiàn),OI的題目背景都相當(dāng)?shù)挠腥?它總是試圖去模擬一個(gè)喜聞樂(lè)見(jiàn)的現(xiàn)實(shí)情況,讓人們會(huì)心一笑.有時(shí)也會(huì)在題目里玩梗.各位可愛(ài)的出題人小哥哥小姐姐的腦洞都是很大的,如果沒(méi)有他們,OI也許也會(huì)充斥著無(wú)聊的經(jīng)驗(yàn)技巧類(lèi)題目...可沒(méi)有暗指什么東西哦.
...
順便這給抽象問(wèn)題帶來(lái)很大麻煩.尤其是一些出題人套背景毫無(wú)藝術(shù)感,題目會(huì)變得很惡心.
思路
太簡(jiǎn)單了,你懂得.
魔法導(dǎo)入:輸入?
為了解決這個(gè)例題,獲取客戶(hù)的點(diǎn)餐是必要的.
輸入設(shè)備有很多,例如鍵盤(pán),鼠標(biāo),掃描儀,攝像頭,以及通過(guò)這些輸入設(shè)備輸入的預(yù)先保存的數(shù)據(jù).針對(duì)這些輸入,有不同的獲取方式.
比賽中(注意不單單NOIP比賽),常見(jiàn)的輸入方式是標(biāo)準(zhǔn)輸入和文件輸入.如何獲取鼠標(biāo),攝像頭,掃描儀一類(lèi)的輸入,請(qǐng)搜索.或者,等我?guī)兹f(wàn)年更新一次添加上.
標(biāo)準(zhǔn)輸入
這個(gè)概念存在于shell.shell會(huì)打開(kāi)3個(gè)標(biāo)準(zhǔn)文件,分別為標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯(cuò)誤輸出
不同于windows.在windows下,文件可能是指圖片,文檔,表格,網(wǎng)頁(yè),游戲存檔...但是屏幕就是屏幕,cpu就是cpu,鼠標(biāo)就是鼠標(biāo).而在linux下,
文件這個(gè)概念并不是只指文件,它可能是電腦的某些硬件!linux將操縱和讀取硬件屬性抽象成對(duì)一類(lèi)特殊的文件的操作.對(duì)的,如果你想操縱硬件,只需要讀寫(xiě)文件!比起windows是不是很有趣?實(shí)際上,linux原本是希望將所有的硬件都表示成文件,可惜在實(shí)際使用上,全面貫徹這種做法不明智,往往在某些情況下,仍然將硬件特殊處理更方便.因此,linux有所取舍.
的確有系統(tǒng)把所有東西都當(dāng)作文件,可以了解一下
plan 9.可以回頭跟別人裝嗶
獲取標(biāo)準(zhǔn)輸入,需要
- 引入適當(dāng)頭文件,在不同的頭文件里有獲取不同輸入的方法
- 從輸入流中得到輸入
頭文件?
這是c++組織代碼的一種方法.想像一下,總不能把10w行代碼寫(xiě)在一個(gè)文件里.當(dāng)把它們拆開(kāi)保存到不同文件里而且還要再進(jìn)行管理時(shí),頭文件就誕生了.頭文件的作用即是通過(guò)
預(yù)編譯指令(下方)將散落在不同文件內(nèi)的代碼鏈接起來(lái).在C++中存在如此的幾種文件.了解就行,競(jìng)賽中用不上.
- .cpp/.cxx 這類(lèi)文件中保存代碼的實(shí)現(xiàn).
- .h 這類(lèi)文件中保存聲明,同時(shí)鏈接實(shí)現(xiàn).c++中的聲明和實(shí)現(xiàn)可以分離,聲明即表示"我們有這個(gè)功能",實(shí)現(xiàn)顧名思義.如此安排自有其道理.
- .hpp 實(shí)現(xiàn)與聲明在同一文件內(nèi)的新格式.目的是為了減少引用的文件數(shù)目.
現(xiàn)在你不用過(guò)多的擔(dān)憂(yōu)什么功能在什么里,在接下來(lái)你總會(huì)漸漸記住,也會(huì)有一個(gè)專(zhuān)門(mén)的表格記載重要的頭文件.
像剛剛說(shuō)的,注意!
- ==標(biāo)準(zhǔn)輸入輸出(standard I/O)在頭文件
iostream內(nèi).==
在代碼開(kāi)頭寫(xiě)如下代碼引入
#include <iostream>
using namespace std;
#include <>是引入某個(gè)頭文件的命令,這行代碼引入了iostream(input/output stream).
我聽(tīng)說(shuō)還有
#include ""對(duì)的.它們的不同體現(xiàn)在查找這個(gè)文件位置的順序.使用
<>會(huì)優(yōu)先尋找標(biāo)準(zhǔn)庫(kù),而""會(huì)優(yōu)先搜索你編寫(xiě)的代碼.至于有毛線(xiàn)用,你可以自己想象,或者未來(lái)能用上的話(huà),會(huì)說(shuō).標(biāo)準(zhǔn)庫(kù)這個(gè)概念將會(huì)在今后漸漸說(shuō)起.
我聽(tīng)說(shuō)
#開(kāi)頭的代碼有特殊作用不錯(cuò),聽(tīng)說(shuō)的很多,能不能把你聽(tīng)說(shuō)的途徑告訴我.以
#開(kāi)頭的代碼叫做預(yù)編譯指令,它將告訴編譯器該如何處理你編寫(xiě)的代碼.還有很多預(yù)編譯指令將會(huì)在后面被介紹.
那行using是啥?
你先這么用著.在競(jìng)賽范圍內(nèi),你不需要這個(gè)知識(shí).但你問(wèn)的好.
1班和2班里都有一個(gè)小孩子叫小明,如何區(qū)分他們?人們于是稱(chēng)他們
1班小明和2班小明.在程序里,往往也有這種問(wèn)題.如果有多個(gè)人同時(shí)給自己的程序起名叫小明,就會(huì)導(dǎo)致問(wèn)題.為了避免這種麻煩,cpp有名字空間的概念.張三和李四寫(xiě)的程序分別放進(jìn)各自的空間,不就如同分班一樣解決了沖突嗎?而
using namespace xxx就是聲明:在你寫(xiě)的程序里,允許xxx內(nèi)的東西全部攙和進(jìn)來(lái).
彈丸里有七海,櫻花莊里也有七海,到底哪個(gè)是哪個(gè)呢?不管了,反正都很可愛(ài).
引用之后,我們獲得了特多的方法和結(jié)構(gòu).其中,有一個(gè)叫做cin.意義可能為c系的輸入(in),用于獲取標(biāo)準(zhǔn)輸入.
使用如下代碼獲取客戶(hù)點(diǎn)的餐.
int order;
cin >> order;
第一行代碼創(chuàng)建(聲明)一個(gè)可以保存整數(shù)的變量(int),它的名字叫order.
==在C++中,聲明一個(gè)變量的語(yǔ)法如<type> <name>.必須記住.==
通用替換法
在魔導(dǎo)書(shū)里,通常使用
<描述>來(lái)標(biāo)記一個(gè)必須填寫(xiě)的空格.使用[描述]來(lái)表示一個(gè)可以忽略不寫(xiě)的空格.這個(gè)標(biāo)準(zhǔn)事先存在,并不是魔導(dǎo)書(shū)瞎創(chuàng)的.
這玩意和數(shù)學(xué)的變量有啥關(guān)系?
emmm它和數(shù)學(xué)的變量還稍稍有區(qū)別.最好別把它們混在一起.
第二行使用>>操作符從cin中取出一個(gè)輸入并存入order.
其實(shí)它還挺象形的不是嗎.
==cin就是iostream中提供的讀取標(biāo)準(zhǔn)輸入的結(jié)構(gòu)==,它就是這個(gè)名字,永遠(yuǎn)是,不管在哪都是.記住.
魔法導(dǎo)入:賦值
你可能在數(shù)學(xué)里見(jiàn)過(guò)這個(gè)神奇的字眼.但最好別把他們混在一起.
在c++中,賦值意味著,將一個(gè)值賦給一個(gè)變量,使用=運(yùn)算符.
對(duì),=并不表示相等,而是賦值,搞清楚.==才表示判斷相等.
觀察下面的代碼.
order = 1;
order = 2;
order = 3;
order = (1==2);
代碼依次使得order中存儲(chǔ)1,2,3,(下方揭曉).
魔法預(yù)導(dǎo)入:運(yùn)算
先扔掉這個(gè)題.嘿,既然我們讀入了一個(gè)整數(shù),可不可以對(duì)它加加減減?
你先造個(gè)計(jì)算器算算帳也不是不可以.
運(yùn)算由運(yùn)算符提供.c++支持加減乘除基本運(yùn)算(抱歉,不支持乘方),以及一些在計(jì)算機(jī)上特有的運(yùn)算.你可能能猜到了怎么表示,但現(xiàn)在我們不討論.
魔法導(dǎo)入:邏輯結(jié)構(gòu)-if
現(xiàn)在我們有客戶(hù)的點(diǎn)餐代號(hào)了,該怎么判斷它是哪個(gè)套餐?
判斷相等
顯然要把代號(hào)和已知的套餐編碼對(duì)比,找出相同的.
如何對(duì)比?
使用<1> == <2>.它會(huì)對(duì)比<1>和<2>.
注意,不能像數(shù)學(xué)那樣寫(xiě)<1> == <2> == <3>,這在C++中是不允許的.如何轉(zhuǎn)化將在運(yùn)算一篇介紹.
上不同的餐
正式介紹if.搭配==,if能夠在相等或者不等時(shí)執(zhí)行不同的代碼,將它用來(lái)處理點(diǎn)餐正好.
if (判斷) //成立那么就執(zhí)行這一條代碼
if (判斷) {
//成立那么就執(zhí)行
}
if (判斷) {
//成立那么就執(zhí)行
} else {
//不成立那么就執(zhí)行
}
if (判斷) {
//成立那么就執(zhí)行
} else if (另一個(gè)判斷) {
//上一個(gè)if不成立但這個(gè)成立那么就執(zhí)行
} else {
//2個(gè)都不成立就執(zhí)行
}
可見(jiàn)if的結(jié)構(gòu)可以說(shuō)比較復(fù)雜了,它的結(jié)構(gòu)差不多就上面那些.
if為一個(gè)固定的關(guān)鍵字,此后緊跟一個(gè)小括號(hào),小括號(hào)內(nèi)填寫(xiě)一段判斷(比如用==連接的判斷).而后跟隨一段代碼,if將會(huì)在判斷成立時(shí)才運(yùn)行這段代碼.
大括號(hào){}表示一塊代碼段,實(shí)際上可以在"任何"地方使用{}圈出一塊區(qū)域?qū)懘a.跟隨在if身后的{}代碼段被if所影響.
避免使用第一種格式
使用第一種格式容易造成理解上的困難(不是說(shuō)它難看...你會(huì)明白的),在使用時(shí)要三思.
注釋
為了更好的理解代碼,在代碼中,你可以使用注釋來(lái)解釋某些代碼的意思(是給人看的).它們不會(huì)對(duì)程序產(chǎn)生任何影響.
- 使用
//來(lái)開(kāi)始一段注釋.可以在新的一行或者每行的結(jié)尾.- 使用
/* [注釋] */來(lái)圈起一大段可以跨行的注釋
作用域
如果你想了解更多的話(huà),
{}實(shí)際上并不是圈出一段區(qū)域?qū)懘a這么簡(jiǎn)單.在c++中,{}同時(shí)圈出了一個(gè)作用域.作用域內(nèi)的聲明會(huì)覆蓋掉作用域外的聲明.意思就是,一旦在新的作用域內(nèi)創(chuàng)建了一個(gè)已經(jīng)存在的變量或者函數(shù),那么在這個(gè)作用域內(nèi)就只能使用新創(chuàng)建的了.同時(shí),在代碼執(zhí)行出作用域后,作用域內(nèi)創(chuàng)建的東西都會(huì)被銷(xiāo)毀.(嚴(yán)格來(lái)說(shuō),是創(chuàng)建在棧上的東西將被銷(xiāo)毀,但暫時(shí)不需要管這么多)可我就是想管
行行行,管管管.在程序運(yùn)行時(shí),內(nèi)存被劃分為2個(gè)不同的區(qū)域.一個(gè)是棧,一個(gè)是堆.棧是有限的且快,堆是無(wú)限的且慢.按照上面解釋的變量創(chuàng)建方法
<type> <name>;創(chuàng)建的基本類(lèi)型變量都存儲(chǔ)在棧上,并會(huì)在作用域結(jié)束后自動(dòng)銷(xiāo)毀.與自動(dòng)相對(duì)應(yīng)的自然就是不自動(dòng),在堆上創(chuàng)建的東西必須手動(dòng)銷(xiāo)毀才能釋放掉內(nèi)存.
將它寫(xiě)成餐點(diǎn)判斷
if (order == 1) {
//點(diǎn)餐是牛肉漢堡
} else if (order == 2) {
//點(diǎn)餐是雞肉漢堡
} else if (order == 3) {
//點(diǎn)餐是薯?xiàng)l
} else {
//點(diǎn)錯(cuò)了,沒(méi)這玩意
}
魔法導(dǎo)入:輸出
繼續(xù)我們的iostream,有了輸入了,自然也有輸出.
給你個(gè)機(jī)會(huì),根據(jù)cin的命名特點(diǎn)猜猜輸出是什么名字.別看了!先別看下面的內(nèi)容!猜完再看.
emmm,知道答案或者確定就是猜不出來(lái)的話(huà),使用鼠標(biāo)劃選下面的黑框框
(mmp居然不能寫(xiě)html代碼,那算了)
<html>
<a style="font-color:black;background-color:black;">cout</a>
</html>
和你猜的一樣嗎?是的,就是這種命名風(fēng)格.
與cin相反的,向輸出流輸出內(nèi)容,使用<<.
為了不影響體驗(yàn),把這玩意放得向下點(diǎn).
.
.
.
.
.
.
.
.
.
cout << "牛肉漢堡" <<endl;
暫時(shí)將endl理解為換行(回車(chē))即可.
如果非想知道,cout內(nèi)部存在緩沖區(qū),endl的作用是輸出并清空緩沖區(qū)...這東西一展開(kāi)講就完蛋了,所以現(xiàn)在先停一停.
流的鏈?zhǔn)讲僮?/strong>
如同你看到的,在這行代碼里同時(shí)出現(xiàn)了兩個(gè)
<<.對(duì)cin和cout的操作都可以如此同時(shí)使用多個(gè)>>``<<,想多少多少.
代碼
然后,這個(gè)點(diǎn)餐程序就是
#include <iostream>
using namespace std;
//正文開(kāi)始
int main() {
int order;
cin >> order;
if (order == 1) {
cout << "牛肉漢堡" <<endl;
} else if (order == 2) {
//點(diǎn)餐是雞肉漢堡
cout << "雞肉漢堡" <<endl;
} else if (order == 3) {
cout << "薯?xiàng)l" <<endl; //點(diǎn)餐是薯?xiàng)l
} else {
//點(diǎn)錯(cuò)了,沒(méi)這玩意
cout << "你點(diǎn)的啥玩意,沒(méi)有,再見(jiàn)" <<endl;
}
return 0;
}
魔法導(dǎo)入:emmmmm多出來(lái)一些東西-c++代碼結(jié)構(gòu)
你注意到上面的代碼多出來(lái)一些東西.在此統(tǒng)一解釋.
c++的程序大概分為2段,預(yù)編譯指令和正文.
在正文部分,出現(xiàn)了莫名其妙的
int main() {
代碼需要有一個(gè)啟動(dòng)的位置.到底該從什么地方開(kāi)始執(zhí)行代碼?這個(gè)函數(shù)給出了開(kāi)始的位置,關(guān)于它更多的內(nèi)容在之后講解.
一睹為快
函數(shù)就是一個(gè)大箱子,把一段常用的代碼(比如算乘方)封起來(lái),方便重復(fù)使用.
main()不止提供啟動(dòng)的位置,同時(shí)會(huì)傳遞啟動(dòng)的命令行參數(shù).
運(yùn)行
至此,代碼就寫(xiě)完了.可以運(yùn)行了.
打開(kāi)一個(gè)shell,輸入
$ g++ <filename>.cpp -o <filename>
$ ./<filename>
按理來(lái)說(shuō),只要你編寫(xiě)無(wú)誤,就可以在這之后按一個(gè)數(shù)字再回車(chē),程序會(huì)告訴你你點(diǎn)了什么.
命令行格式
在上面的命令中,每行前都帶有一個(gè)
$.它表示一段命令的開(kāi)始,請(qǐng)忽略掉,不要一同輸入.類(lèi)似的還有
#.二者有不同的含義,但是對(duì)我們來(lái)說(shuō)沒(méi)啥用.
結(jié)
實(shí)際上,你可能只會(huì)了目標(biāo)里的一點(diǎn)點(diǎn).
其他的會(huì)說(shuō)的.