第一桶 從C到C++ 第四碗 陳老C教研室論道 潘小P書(shū)桌前練功
"呵呵,算你小子有良心。"老C心滿意足的摸著肚子。"嗯,嗯。"小P有一搭沒(méi)一搭的回答著,一邊數(shù)著自己的錢包。
"哈哈,別難過(guò)了,下回我請(qǐng)你,還去這家。那個(gè)醬骨頭味道還真是不錯(cuò)啊。"老C承諾道。
"哦~哦~,我看你是沒(méi)有吃到刀削面懷恨在心吧,k,好像你餓了一個(gè)星期一樣,沒(méi)見(jiàn)過(guò)這樣吃肉的。"小P很是傷心。
"哈哈,說(shuō)好了下回我請(qǐng)你的……"
"我沒(méi)有你吃得多……"小P有些郁悶。
"嗯,我們先把飯量問(wèn)題放一邊,我來(lái)幫你裝eclipse和CDT吧。"老C開(kāi)始轉(zhuǎn)移話題。
"對(duì)了對(duì)了,正事都快忘了。"
感謝教育網(wǎng)的網(wǎng)速和老C的幫助,小P很快裝好了eclipse,在老C的指導(dǎo)下寫了一個(gè)Hello world,算是正式上路了。
"我們以后都要這樣開(kāi)始,"老C不知道從哪里摸出一副眼鏡架在鼻子上,"一個(gè)問(wèn)題,一段代碼。問(wèn)題就像正式項(xiàng)目中的需求,而代碼就像我們正式的產(chǎn)品。在從需求到產(chǎn)品的過(guò)程中,我們會(huì)明白C++的哪些技術(shù)是因?yàn)槟姆N需求而產(chǎn)生的,這樣以后你遇到類似的問(wèn)題時(shí),就會(huì)使用正確的方法或者技術(shù)去解決問(wèn)題了。"老C扶了扶眼鏡,"不過(guò)在此之前……我要去喝點(diǎn)茶……,好了好了,開(kāi)玩笑的。不過(guò)我真的要問(wèn)一個(gè)很嚴(yán)肅的問(wèn)題,你考試成績(jī)那么好,是不是分析問(wèn)題,解決問(wèn)題的能力就真的那么好呢?"
"那是自然,我的排名可是不低的呢。"
"好吧,我想問(wèn)問(wèn)你什么是分析問(wèn)題,解決問(wèn)題的能力?"
"多做題,能力自然就上來(lái)啦。當(dāng)我在考試時(shí)遇到一個(gè)問(wèn)題,我會(huì)想做過(guò)的類似的習(xí)題或者例題,然后采用同樣的方法再做一遍啊。"
"那么要是從來(lái)沒(méi)有做過(guò)的類型呢?"
"不可能,我復(fù)習(xí)的時(shí)候是很認(rèn)真的。"
"……那么你遇到陌生的問(wèn)題怎么辦?"
"分析嘍……"
"算了,看來(lái)你真是實(shí)實(shí)在在的經(jīng)驗(yàn)主義啊。"
"那你說(shuō)什么是分析問(wèn)題,解決問(wèn)題的能力?"
"就我的感覺(jué),分析問(wèn)題其實(shí)是對(duì)問(wèn)題歸類。因?yàn)樵诂F(xiàn)實(shí)生活中,我們其實(shí)不用發(fā)明什么解決問(wèn)題的方法,因?yàn)槟敲炊嗫茖W(xué)家、牛人和前輩已經(jīng)把解決問(wèn)題的方法放到那里了,我們只是要找到這個(gè)方法而已……"老C開(kāi)始口噴漠漠,“比如你解微分方程,就要看是常系數(shù)還是變系數(shù),是齊次還是非齊次,等等,如果你將方程歸入某一類,那么解法也就順其自然了,關(guān)鍵是你要?dú)w類正確,然后你就站在巨人肩膀上了。"
"哦?聽(tīng)你一說(shuō),我感覺(jué)我做題的時(shí)候的確是要仔細(xì)閱讀題目,看看它是想考察哪一類問(wèn)題或方面的……那么所謂解決問(wèn)題的能力你認(rèn)為是什么呢?"
"我覺(jué)得所謂解決問(wèn)題的能力是對(duì)細(xì)節(jié)的理解和掌握程度,細(xì)節(jié)理解得越透徹,解決問(wèn)題的能力越強(qiáng)。同時(shí)如果你細(xì)節(jié)理解得越明白,越容易掌握此類問(wèn)題的根本。"
"哦?說(shuō)來(lái)聽(tīng)聽(tīng)。"
"比如讓你來(lái)求解一個(gè)函數(shù)的最值問(wèn)題,你會(huì)怎么做?"
"這 個(gè)難不倒我,”小P很是自信,“我數(shù)學(xué)可不賴的。我需要先對(duì)函數(shù)求一階導(dǎo)數(shù),找到它的拐點(diǎn),然后求二階倒數(shù),看它在拐點(diǎn)上是上凹還是下凹,來(lái)判斷這些 拐點(diǎn)處的數(shù)值是極大值還是極小值;如果函數(shù)在所求范圍內(nèi)沒(méi)有極點(diǎn),那么我會(huì)判斷它是單調(diào)增還是單調(diào)減函數(shù),然后看函數(shù)在所求范圍的邊界是否連續(xù),邊界范圍 是否可達(dá);最后不要忘了函數(shù)的非連續(xù)點(diǎn),因?yàn)榉沁B續(xù)點(diǎn)上函數(shù)不可導(dǎo),所以要單獨(dú)看看。"小P想了想,"哦,如果函數(shù)處處不可導(dǎo)而處處連續(xù)的話,或者根本就處處不連續(xù),那么就要靠人品構(gòu)造一些函數(shù),運(yùn)用夾逼法則,但是一般不會(huì)這么bt的。當(dāng)求出以上所有點(diǎn)后,比較一下,最大的就是最大值,最小的就是最小值。"
"……佩服佩服,"老C鼓掌,“怪不得你的成績(jī)好,看來(lái)你是很下功夫的。不錯(cuò),這些就是對(duì)細(xì)節(jié)的了解,說(shuō)明起碼你 在這個(gè)方面解決問(wèn)題的能力很強(qiáng)!看,你了解求導(dǎo)的前提是要連續(xù),而且了解導(dǎo)數(shù)為零的地方是函數(shù)的拐點(diǎn),并且也了解到有可能函數(shù)在拐點(diǎn)處不可導(dǎo),同時(shí)你還根 據(jù)環(huán)境對(duì)函數(shù)進(jìn)行了正確的分類:處處可導(dǎo),處處連續(xù)但非處處可導(dǎo),處處連續(xù)處處不可導(dǎo)和非處處連續(xù)以及處處不連續(xù),然后根據(jù)這些分類、足夠充分的細(xì)節(jié),良 好的解決了這個(gè)問(wèn)題。"
"呵呵,是啊,但是這個(gè)和C++有什么關(guān)系?"
"有關(guān)系,”老C肯定的說(shuō),“ 與做高數(shù)題目是一樣的道理,我們?cè)谧鯟++編碼時(shí),首先要注意問(wèn)題發(fā)生的環(huán)境——也就是上下文,我們需要根據(jù)問(wèn)題所處的環(huán)境與需求對(duì)問(wèn)題分類,這需要我們 收集足夠多的信息;然后根據(jù)這類問(wèn)題一般的解決通法列出解決此類問(wèn)題的方案,再根據(jù)具體需求和上下文在方案中挑選,或者對(duì)此方案進(jìn)行修改以滿足具體需求, 在這里我們需要關(guān)注足夠的細(xì)節(jié),才可以采納較優(yōu)的方案;最后根據(jù)需求進(jìn)行評(píng)審,尋找是否還有更好的方案。這只是開(kāi)發(fā)的一般步驟,在具體開(kāi)發(fā)中這些活動(dòng)是迭 代進(jìn)行的,從需求分析到代碼實(shí)現(xiàn),這些活動(dòng)重復(fù)的出現(xiàn)在軟件開(kāi)發(fā)的各個(gè)階段——但是我們得首先解決的問(wèn)題是,你先要知道可能的分類有哪些,然后再根據(jù)所處 的環(huán)境和需求,去逆向思維,尋找解決之道。綜合起來(lái)講,解決問(wèn)題的方法就是一般逆向思維的方法,而逆向思維總是靠猜測(cè)和試驗(yàn)的,至于猜得好不好或者試驗(yàn)的 對(duì)不對(duì),就要靠經(jīng)驗(yàn)了,如果你的經(jīng)驗(yàn)夠豐富,能夠根據(jù)逆向思維的結(jié)果總結(jié)出來(lái)一套方法,順著這個(gè)方法你總可以找到正確的問(wèn)題分類——那么恭喜你,你離大師 也不遠(yuǎn)了。你看看,是否和解決生活中其他技術(shù)問(wèn)題的方法是一樣的呢?”
“好像是的,感覺(jué)如果不是創(chuàng)造性的活動(dòng)的話,還真是這樣的,不過(guò)就算是創(chuàng)造性活動(dòng)或者科研活動(dòng),也需要對(duì)問(wèn)題進(jìn)行分類,然后研究看看前人都做了哪些成就可以借鑒的。”小P點(diǎn)點(diǎn)頭。
“好了,形而上的東西我們就聊這么多,現(xiàn)在看看形而下的東西。”老C從旁邊拉過(guò)白板,在上面畫(huà)了一個(gè)圓,在順時(shí)針?lè)较驑?biāo)上了箭頭,并在旁邊寫下“誰(shuí)是最后一個(gè)幸運(yùn)兒?”“這是一個(gè)很常見(jiàn)的問(wèn)題,可能出現(xiàn)在各大招聘筆試題目中。”
“哦?”
“話說(shuō)有一幫倒霉孩子——嗯,有20個(gè)吧——排排坐,吃果果,但是由于資源匱乏,金融危機(jī)等原因,很不幸——只有一個(gè)果果。那么這個(gè)果果分給誰(shuí)呢?老師決 定,把他們排成一個(gè)圓圈,按順時(shí)針?lè)较驑?biāo)號(hào),12點(diǎn)鐘的小朋友是1號(hào),以此類推。然后從1號(hào)小朋友開(kāi)始,依次報(bào)數(shù),數(shù)到……嗯……7的小朋友就被踢出隊(duì) 伍,下一個(gè)小朋友接著從1開(kāi)始數(shù),直到隊(duì)伍中有且僅有一個(gè)小朋友。請(qǐng)問(wèn),如果你在這個(gè)隊(duì)伍中,你會(huì)挑選幾號(hào)坐位,從而吃到果果呢?”老C停了一下,“你現(xiàn) 在也裝好了eclipse,正好可以練練,一開(kāi)始先用C寫吧,然后我們?cè)僬務(wù)揅++的解決之道。我剛才吃得有點(diǎn)多,得去喝點(diǎn)茶……”于是留下小P一個(gè)人, 拿著茶杯出門接開(kāi)水去了。
“嗯,這個(gè)問(wèn)題不是很難,”小C自言自語(yǔ),“我只要有一個(gè)循環(huán)隊(duì)列就可以解決了……”他先是在一張紙上畫(huà)了一個(gè)圓圈,并安排了5個(gè)小朋友玩這個(gè)游戲,試了兩下,覺(jué)得自己理解的差不多了,就開(kāi)始在鍵盤上扣扣扣扣的敲代碼……
老C回來(lái)后看到小P正在忙,也沒(méi)有打擾他。他一邊吹氣一邊慢慢喝完杯子里的水,順便在起點(diǎn)上看了幾篇yy的穿越水文,估摸著小P差不多了,轉(zhuǎn)過(guò)椅子問(wèn):“怎么樣?差不多了吧?”
“等等,還有一個(gè)問(wèn)題……好了好了,最后一個(gè)留下的是2號(hào)小朋友。”
“你確認(rèn)?”
“等等我還得再看看……”小P又是一番手忙腳亂,“好吧,我基本確定是2號(hào)小朋友……”
“?”老C很是好奇,“為什么是基本上?”
“因?yàn)?#8230;…這個(gè)……我還需要一段調(diào)試時(shí)間才可以確定……”
“算了,我們來(lái)直接看看代碼好了。”
“好啊,寫得不好請(qǐng)多批評(píng)。”小P假裝謙虛道,心想自己的代碼應(yīng)當(dāng)還是不錯(cuò)的。
“是這個(gè)a.c文件嗎?”
“是的是的,呵呵。”
老C于是做到小P旁邊review他的代碼。
#include <stdio.h>
void main()
{
int a[20];
int b;
int m;
int k;
int N=20;
for(m=0;m<20;++m){
a[m]=1;}
m= 0;
b =1;
while(N>1)
{ if(a[m]!=0)
{
if (b==7){
a[m] = 0;
--N;
if (N==1)
{break;
}
b=1;
}
else{
++b;
}
}
++m;
m%=20;
}
for(k=0;k<20;++k){
if (a[k]==1)
{break;}
}
++k;
printf("%d\n", k);
}
“我看不懂……”老C才看了30秒就決定放棄了。
“不會(huì)吧,我覺(jué)得我寫得邏輯性還挺清楚的啊。”小P有些得意老C看不懂他寫的代碼,覺(jué)得可能自己寫的邏輯過(guò)于高深了。
“……”老C沉默了半分鐘,“這個(gè)不是C代碼!”他肯定的說(shuō)道,“所以我看不懂,也不想看懂。”
“?”小P有些奇怪,“這明明就是C語(yǔ)言寫的代碼啊,你看,我來(lái)給你解釋解釋……”
“哦,算了,這些根本不是C代碼,我沒(méi)有必要看懂。”
“那你說(shuō)這些是什么?”小P有些不高興了。
“這些是……”老C找著合適的形容詞匯,“這些是貓爬過(guò)屏幕的腳印,我沒(méi)有必要看懂腳印所代表的含義……”看到小P有些驚愕,然后開(kāi)始有些生氣,逐漸開(kāi)始 惱羞成怒了,老C趕快對(duì)他說(shuō):“呵呵,別生氣了,我開(kāi)玩笑的,不過(guò),”老C的語(yǔ)氣嚴(yán)肅起來(lái),“這些的確是很糟糕的代碼,哪怕它的算法多么高效,執(zhí)行效率多 么高,它都是糟糕的代碼!”
“為什么?”從來(lái)沒(méi)有人說(shuō)過(guò)小P的代碼糟糕,聽(tīng)了老C的評(píng)論他覺(jué)得一時(shí)無(wú)法接受。
“我們先不評(píng)論代碼正確與否,單單是它的格式和縮進(jìn)……”老P用鼠標(biāo)在代碼上劃來(lái)劃去,“就無(wú)法讓人提起評(píng)審它的欲望。”老C真誠(chéng)的看著小P,“你一定沒(méi)有參加過(guò)比較大型的,3、5個(gè)人合作開(kāi)發(fā)的項(xiàng)目吧?”
“是啊,學(xué)校里面哪里來(lái)的機(jī)會(huì)?”
“唉,所以說(shuō)教育失敗啊。”老C有些感慨,“即使沒(méi)有參加過(guò)項(xiàng)目,基本的規(guī)范性的東西學(xué)校還是要教的啊,算了,這個(gè)不是你的錯(cuò),是老師的錯(cuò),是學(xué)校的錯(cuò)。”
“嗯……”聽(tīng)到老C說(shuō)不是自己的錯(cuò)誤,小P開(kāi)始平靜下來(lái)。
“言之無(wú)文,行而不遠(yuǎn),是什么意思?”老C問(wèn)道。
“就是說(shuō)如果一篇文章不夠優(yōu)美,那么它就流傳不廣。”小P還是比較油菜的。
“是啊,代碼也是一樣的啊。如果它的格式有問(wèn)題,大家不喜歡看,也就沒(méi)有人維護(hù),這樣的代碼很快會(huì)被替換掉,哪怕它背后閃爍著照耀銀河系的智慧的光芒!”
“是嗎?”小P有些不相信。
“好吧,我們?cè)囋嚕?#8221;老C決定不要再打擊可憐的孩子了,“我們把這個(gè)代碼放一段時(shí)間——就一個(gè)星期吧——反正我們這周有兩個(gè)講座要聽(tīng),等到周末的時(shí)候你再講講你的代碼,如何?”
“沒(méi)有問(wèn)題,就10幾行代碼么,我就不相信我記不住!”小P有些和老C對(duì)上了。
(to be continued...)
posted on 2009-01-20 00:05 Anderson 閱讀(2106) 評(píng)論(5) 編輯 收藏 引用