• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流

                 公園2003年,秋。
                 西安。
                 晴,黃歷上寫——易出行,交友。
                 交大東二樓。
                 笑容,邪邪的笑容浮現(xiàn)在他英俊自信驕傲的臉上……
                 
                 (以下轉(zhuǎn)正常)
                 今天是新碩士報道后的第一天,小P一早就高高興興的向教研室走去。“嗯,應(yīng)該可以見到有趣的家伙吧。”他想。他很是期待見到新同學(xué)和結(jié)交新朋友。到Z老板辦公室和老板打過招呼后,他向?qū)嶒?yàn)室走去。“聽說一個工作了3年的家伙已經(jīng)到了,不知道是不是邪惡大叔啊。”小正太一邊走一邊邪惡的想著。推門進(jìn)去發(fā)現(xiàn)一個高大沉穩(wěn)老練的男人正在收拾電腦桌,呵呵,他的美人尖還透露出他的智慧。
                 “你好,我叫小P。”
                 男人回過頭:“呵呵,你好,我叫陳老C,你長得還真是年輕啊。”
                 “呵呵,幼稚,幼稚而已。”
                 “你是本科后直接上研的吧?”
                 “是啊是啊,聽說你工作了3年?”
                 “沒錯,我是96級的,工作3年以后又回學(xué)校來啦……”
                 ……
                 “……我做過一些項(xiàng)目,有用C做的,有用C++做的……”老C和小P聊的不錯,感覺還挺投緣的。
                 “哦,我也用C寫過一些小的程序,C++課程也學(xué)習(xí)過,成績還挺不錯的。”小P開始吹牛了,“C++是C語言在面向?qū)ο蠓矫娴陌l(fā)展……”
                 “噢,這么說也沒有什么錯,開始的時候C++的確是C在面向?qū)ο蠓矫娴陌l(fā)展,但是……”老C開始給小P上課了,“現(xiàn)在C++其實(shí)是一個語言的聯(lián)邦,在它的內(nèi)部存在4種不同的語言……”
                 “是嗎?”
                 “是的,這4種語言包括C——這是理所當(dāng)然的——同時還包括面向?qū)ο蟛糠郑瑃emplate部分和STL部分,每個部分都有其獨(dú)特的考慮問題的方式,有著自己獨(dú)到的習(xí)語和風(fēng)格……”
                 “習(xí)語?風(fēng)格?”
                 “是的。”老C解釋道,“我們學(xué)習(xí)編程語言就像學(xué)習(xí)一般的語言一樣——比如英語——如果你只是掌握了英語的基本語法你可以和英國人或者美國人自由的交流嗎?”
                 “我想應(yīng)該不行吧,我想我可能不理解他們所說的……比如詞匯……”小P回答道。
                 “對,你有沒有發(fā)現(xiàn)當(dāng)我們即使掌握了某種語言的語法也無法和其他人進(jìn)行有效的交流的時候,就是說你對某段語言所表達(dá)的意思不了解的時候,一般都是如何不了解的?”
                 “哦?這個我還沒有仔細(xì)考慮過。讓我想想……”小P以手撐頭,陷入沉思狀……“我試著總結(jié)一下,應(yīng)當(dāng)是對以下幾方面不了解。”小P開始噴了。
            1. 對語言的基本單元無法理解,在英語里面應(yīng)當(dāng)是詞匯。
            2. 對句子無法理解,尤其是一些句型不了解,比如英語里面的too...to句型。
            3. 如果單詞理解了,句子也理解了,但是還是無法理解一段語言,那么應(yīng)當(dāng)是思維方式與說這段話的人有距離。
                 “沒錯!”老C稱贊道,“你還真是聰明啊,這么短時間就可以總結(jié)個子丑寅卯出來。”
                 “呵呵,哪里哪里,我就是比較油菜而已……”
                 “哈哈,那我們就拿你的總結(jié)與C++對比一下吧。”
            1. 單詞就像C++里面的慣用習(xí)語,比如virtual constructor或者PIMPL等
            2. 句型就像設(shè)計模式。
            3. 思維方法就是語言風(fēng)格。
                 “不懂,什么是virtual constructor和PIMPL?什么又是設(shè)計模式?語言風(fēng)格又是什么東東?”小P開始懷疑老C是火星人,他說的是漢語嗎?
                 “沒有關(guān)系,以后我們還有機(jī)會來討論那些C++常用的習(xí)語,現(xiàn)在我們就幾個常見的思維方式,也就是語言風(fēng)格的問題舉幾個簡單的例子吧。”老C從實(shí)驗(yàn)室的角落拉過來一塊白板,又找出一支彩筆開始在白板上畫了起來。
                 “我這里現(xiàn)在有一個簡單的問題,”老C在白板的上面寫下幾行文字。

            設(shè)計一段代碼,這段代碼需要根據(jù)不同的輸入在屏幕上打印對應(yīng)的水果名稱

                 “能具體一些嗎?”小P問。
                 “可以啊,我寫開始的一段代碼,你補(bǔ)全如何?”
                 “想考我嗎?沒有問題……呵呵。”
                 老C開始在白板上寫代碼,“我們意思意思就可以了,在這里我們使用C語言,所以是C語言的風(fēng)格”。
                 “C?這個我還比較擅長。”小P現(xiàn)在有些想露一手。
                 “好吧,看看我們?nèi)绾瓮瓿伞?#8221;老C刷刷幾筆寫下了如下代碼。
            typedef enum tagFRUIT{ORANGE, APPLE, BANANA} FRUIT;
            void PrintFruitName(FRUIT fruit)
            {
            }
                 “嗯,容易……”小P開始完成PrintFruitName()函數(shù)。
            void PrintFruitName(FRUIT fruit)
            {
                switch (
            fruit)
                {
                case ORANGE:
                    pirntf("orange\n");
                break;
               
                case APPLE:
                    printf("apple\n");
                break;
               
                case BANANA:
                    printf("banana\n");
                break;
               
                default:
                    return;  
                }
            }

                  “好了,我們的算法是這樣的,一個函數(shù)從某處——無論什么地方,鍵盤輸入也好,某個配置文件也好——讀到了需要輸出的蔬果信息,然后調(diào)用我們的打印函數(shù)將水果名稱打印出來。”老C說完寫下了完整的main()函數(shù)。

            int main()
            {
                FRUIT fruit;
               
                /* Get the information of fruit. */
                fruit = GetFruitInfo();
                /* Print the name of the fruit. */
                PrintFruitName(fruit);

                return 0; 
            }

                 “Perfect!”小P高興的說道。
                 “嗯,只能說不錯而已,完美還談不上。”老C點(diǎn)點(diǎn)頭,“如果我們希望添加一種新的水果到我們的系統(tǒng)里面,比如梨,pear,怎么辦?”
                 “好辦啊,我只要在FRUIT的枚舉類型中添加PEAR,然后在PrintFruitName()函數(shù)中添加一個case分支就可以了,有什么復(fù)雜的?”
                 “呵呵,注意你剛才用了兩個添加的詞語,表示你有兩次添加的動作……”
                 “這又有什么不可以的呢?”
                 “沒有什么不可以,只和問題的規(guī)模有關(guān),但是,”老C停頓一下,“這里我想強(qiáng)調(diào)的是語言風(fēng)格的問題……”
                 “?”小P開始集中注意力。
                 “因?yàn)槲覀儫o法擺脫語言對思維方式的影響,反過來思維方式表現(xiàn)在代碼上就是風(fēng)格,”老C指指白板,“比如這個PrintFruitName()函數(shù),就是一個很典型的C風(fēng)格函數(shù)。”
                 “為什么呢?”
                 “因?yàn)樗?#8230;…”老C嘆了口氣,“我不知道怎么形容,只好說的陳詞濫調(diào)一些——因?yàn)樗嫦蜻^程。”老C撓撓頭,“不,確切的說它掌握了太多的細(xì)節(jié)……”
                 “聽不懂……”小P有些囧。
                 “好吧,那么讓我們來換個角度看問題。假如你現(xiàn)在是個測試工程師……什么叫測試工程師?就是保證代碼質(zhì)量的……”老C面對一個技術(shù)幼齒有些郁悶,“他們按照一定的步驟對代碼進(jìn)行測試,包括檢視代碼、使用特殊輸入數(shù)據(jù)檢驗(yàn)代碼質(zhì)量等等……”老C開始結(jié)巴了,“你就認(rèn)為是專門檢查代碼的算了。”
                 “好吧,然后呢?”
                 “假如你剛才已經(jīng)檢查過我們寫下的所有代碼,并認(rèn)為它們都是正確的,這個時候有個家伙說因?yàn)樾枨笞儎有枰黾覲EAR到系統(tǒng)中,并且需要改動水果名稱的輸出格式,他剛剛更改了PrintFruitName()函數(shù),需要你去做檢查,你會怎么辦?”
                 “涼拌!讓他把他改過的部分圈出來,我看他改的對不對。”
                 “哦,這樣會有問題的……”
                 “什么問題?”
                 “假如這個家伙是500/2,他在增加case PEAR:分支到BANANA下面的時候不小心刪除了BANANA分支的break……”
                 “餓滴神啊,這樣在函數(shù)輸入形參如果是BANANA,那么結(jié)果真是出人意料啊!”
                 “是啊是啊,所以……”
                 “所以如果是由我檢查代碼,我可不能聽信那個家伙的話,只看他自以為修改過的部分,是吧。”小P開始有些理解了。
                 “是啊,你必須把今天早上做過的所有檢查再做一遍,來確保那個家伙沒有搗亂……”
                 “啊,那么重復(fù)的工作量豈不是很大?”小P開始覺得測試工程師個個都是雙眼通紅,走路帶晃的ggmm,“那么我們有什么好辦法呢?”
                 “在C語言范圍內(nèi)還是有一些方法的……”老C說道,“只是都比較麻煩而已。”
                 “是么?讓我想想……”小P開始開動腦筋,幾分鐘后,他有些失望,“我想不出什么好方法,老C,你有什么辦法?”
                 “我們可以使用回調(diào)函數(shù),或者使用指向函數(shù)的指針……”
                 “?”小P眼睛成星星狀,“怎么做?”
                 老C開始挽袖子,并在白板上涂涂抹抹。

            typedef enum tagFRUIT{ORANGE, APPLE, BANANA} FRUIT;
            typedef void (*PRINT_PROC)(char*);
            typedef struct tagFRUIT_INFO
            {
                FRUIT               fruit_;   
               
            const char* const   name_;
            }FRUIT_INFO;

            void DoPrintFruitName(char* name)
            {
                printf("%s\n", name);
            }

            void DoPrintFruitNameCompany(char* name)
            {
                printf("XJTU's %s\n", name);
            }

            const FRUIT_INFO g_fruitInfo[] =
            {
                ORANGE,    "orange"
                ,APPLE,    "apple"
                ,BANANA,   "banana"
            };

            void
            PrintFruitName(FRUIT fruit, PRINT_PROC printProc)
            {
                int i;
               
                for (
                     i = 0;
                     i < (sizeof(g_fruitInfo)/sizeof(g_fruitInfo[0]));
                     ++i
                    )
                {
                    if (g_fruitInfo[i].fruit_ == fruit)
                    {
                        (*printProc)(g_fruitInfo[i].name_);
                    }
                }
            }

            int main()
            {
                FRUIT fruit;
               
                /* Get the information of fruit. */
                fruit = GetFruitInfo();
                /* Print the name of the fruit. */
                if (/* Print fruit's company. */)
                {
                    PrintFruitName(fruit,
            DoPrintFruitNameCompany);
                }
                else
                {
                    PrintFruitName(
            fruit, DoPrintFruitName)
                }

                return 0;
            }


                 “這樣,”陳老C解釋道,“如果我需要增加PEAR到系統(tǒng)中,只需要在g_fruitInfo的表格中增加一行就可以了。而且程序可以根據(jù)外部的需求決定是否輸輸出產(chǎn)水果的公司,當(dāng)然這些都是說明性的,用偽代碼代替了。”
                 “*^*”小P看的有些眩暈,“我有些頭暈,像暈車……”
                 “沒有關(guān)系,只是你不熟悉罷了。”老C摸著下巴,“這就是我說的風(fēng)格問題,因?yàn)樗伎紗栴}的方式不同導(dǎo)致代碼的風(fēng)格看起一時難以接受而已。”
                 “哦?看來只是習(xí)慣問題?那么我再看看……”克服了暈車般的頭痛,小P又看了幾遍代碼,感覺依照自己的C基礎(chǔ),看懂是沒有問題的,畢竟自己還是很油菜的。“的確是習(xí)慣問題,但是為什么老C會這樣思考問題呢?”小P想。
                 “因?yàn)樾畔㈦[藏……”
                 “你怎么知道我在想什么?”
                 “因?yàn)槟阍谧匝宰哉Z!”老C很是囧,“我們來看看現(xiàn)在的代碼吧,它與我們第一版的代碼區(qū)別在于信息的隱藏和信息的外部存儲。原來的PrintFruitName()信息都存儲在函數(shù)內(nèi)部,即函數(shù)需要知道具體的FRUIT枚舉才可以做出相應(yīng)的輸出,而且輸出數(shù)據(jù)的格式信息也存儲在函數(shù)中。這樣這個函數(shù)就和我們的需求緊密結(jié)合,就是說如果我們的需求——水果類型和輸出名稱的信息及格式——任何一個發(fā)生變化,那么這個函數(shù)體本身也必須發(fā)生變化,代價就是——寫代碼的人和測試代碼的人都強(qiáng)烈拒絕新的需求變化。而如果我們把具體信息對PrintFruitName()隱藏,使得函數(shù)只知道在一個表格中尋找對應(yīng)的類型,然后根據(jù)自己接口處的函數(shù)指針調(diào)用格式化輸出函數(shù),那么在需求發(fā)生變化時,我們只需要修改具體保存信息的數(shù)據(jù)格式——比如g_fruitInfo表格,而無需修改函數(shù)體本身;更炫一點(diǎn)兒的是,我們還可以使用宏把對g_fruitInfo表格的操作封裝起來,防止維護(hù)人員對g_fruitInfo表格進(jìn)行誤操作……但是考慮到你的承受能力,我們以后再談?wù)撨@個話題。這樣,就產(chǎn)生了相對穩(wěn)定的結(jié)構(gòu)——PrintFruitName()函數(shù)體,但是此設(shè)計又沒有拒絕維護(hù)人員根據(jù)需求進(jìn)行變更……
                 “哦,讓我再想想……”小P又回頭去看代碼,“這次感覺好多了,但是,”小P開始惡狠狠的對老C說,“你一早就這么寫出來得了,為什么還要我浪費(fèi)時間啊!”
                 “我又沒有說你寫得不好,如果是我第一次寫,我也會寫得和你一樣!”
                 “?”
                 “一切都由需求而定!我們一開始時并不知道哪些需求會發(fā)生變化,因此只要滿足現(xiàn)有需求就可以了,所以你一開始寫的代碼并沒有什么不妥……問題發(fā)生在需求變化之后,”老C加重了語氣,“現(xiàn)在我們已經(jīng)知道需求可能在那些地方變化,而且就現(xiàn)實(shí)情況而言,一旦需求在某處發(fā)生變化,那么它就會經(jīng)常在此處發(fā)生變化。這個時候我們就需要對程序結(jié)構(gòu)進(jìn)行調(diào)整,以應(yīng)對這種變化,而不只是在原來的基礎(chǔ)上縫縫補(bǔ)補(bǔ)……那樣會帶來很多重復(fù)性的勞動!”
                 “……槑”
                 “算了,這些都是隨著編碼規(guī)模的增大而得來的經(jīng)驗(yàn),相信你以后會逐步明白的,我看好你哦!”
                 “謝謝啊!”
                 “總之這就是思維的差異帶來的代碼風(fēng)格的差異,我也是在用C++進(jìn)行了幾次項(xiàng)目之后才慢慢明白的,如果只是單純的游弋在C語言的世界,我覺得我要明白這些東西還需要很長時間啊。”
                 “這個和C++有什么關(guān)系?”小P有些不解。
                 “當(dāng)然有關(guān)系了,因?yàn)槭褂昧薈++后,我思考問題的方式與只使用C的時候發(fā)生了很大的不同,因?yàn)樗季S方式的不同,導(dǎo)致我的C代碼風(fēng)格發(fā)生了很大變化……但是話說回來,每種風(fēng)格沒有好壞的區(qū)別,只有合適不合適的區(qū)別。等我們打掃完實(shí)驗(yàn)室,我們再試試怎么用C++改寫這些代碼,至于現(xiàn)在,時候也不早了,我們?nèi)コ晕顼埌桑?#8221;制止住又想發(fā)問的小P,老C拉起他就向門外走。
                 “哎哎,我還有問題要問呢,要不吃飯的時候你再噴噴……”


                 (未完待續(xù))
                 (請勿轉(zhuǎn)載,謝謝!)

            posted on 2009-01-18 02:08 Anderson 閱讀(2666) 評論(12)  編輯 收藏 引用

            評論

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流 2009-01-18 19:51 蟲牙

            支持
            狂頂  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流 2009-01-19 13:15 likenk

            ^_^,道理和MFC中的消息映射一樣。  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流[未登錄] 2009-01-19 15:09 Anderson

            @likenk
            沒錯!就是DECLAR_DYNAMIC和IMPLEMENT_DYNAMIC做的事情,而后面的具體實(shí)現(xiàn)函數(shù)就像On_XXX一樣。^_^  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流 2009-01-20 13:50 李現(xiàn)民

            這種風(fēng)格, 挺好  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流 2009-01-20 15:18 Auguste

            這樣寫,挺好的,希望能繼續(xù)下去!  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流[未登錄] 2009-01-22 16:56 Len

            不錯阿,從敘述到代碼風(fēng)格,都是非常認(rèn)真
            講得東西也非常有吸引力  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流 2009-02-19 15:28 霜之哀傷

            nice  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流 2009-03-28 21:15 funcoding

            支持,請繼續(xù)  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流 2009-04-18 21:38 wqf

            太贊了!咱交大有才的人咋就這么多!  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流[未登錄] 2009-09-01 19:25 wstonep

            支持!!!!  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流 2009-10-02 18:38 ddlau

            我這是第二次看你的文章了,第一次因?yàn)橐恍┚壒蕸]能看完~
            寫的對我來說很好,很有幫助,謝謝  回復(fù)  更多評論   

            # re: 第一桶 從C到C++ 第一碗 潘小P初登教研室 陳老C笑談顯風(fēng)流 2010-09-04 15:47 JasonRen

            初看adapter代碼的時候沒有發(fā)現(xiàn),仔細(xì)想想里面從架構(gòu)到模塊實(shí)現(xiàn)都采用了這種思想!帥帥說代碼寫得好,但當(dāng)時我沒有發(fā)現(xiàn)好在什么地方,現(xiàn)在有體會了!用c++的語言風(fēng)格在C中實(shí)現(xiàn)!!回頭再仔細(xì)分析一下!
              回復(fù)  更多評論   


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            <2009年1月>
            28293031123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            留言簿(6)

            隨筆檔案(21)

            文章檔案(1)

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            99久久99久久精品国产| a级毛片无码兔费真人久久| 久久久久久一区国产精品| 久久996热精品xxxx| 人妻无码精品久久亚瑟影视| 国产精品中文久久久久久久 | 精品久久无码中文字幕| 久久久久无码精品国产| 国产成人久久777777| 久久天天躁狠狠躁夜夜avapp | 婷婷国产天堂久久综合五月| 久久精品99无色码中文字幕| 久久婷婷五月综合色99啪ak| 精品精品国产自在久久高清| 国产午夜福利精品久久| 国产伊人久久| 亚洲va久久久久| 99久久成人国产精品免费| 欧美久久精品一级c片片| 久久精品成人一区二区三区| 欧美激情一区二区久久久| 色老头网站久久网| 久久丫精品国产亚洲av不卡| 久久精品国产免费| 久久久久中文字幕| 亚洲国产成人精品女人久久久| 亚洲精品国产成人99久久| 奇米影视7777久久精品人人爽| 国产精品一区二区久久| 亚洲国产精品成人久久蜜臀| 熟妇人妻久久中文字幕| 欧美激情精品久久久久久久| 国产成人久久激情91| 亚洲欧洲精品成人久久曰影片| 97久久超碰国产精品2021| 2021久久精品免费观看| 国色天香久久久久久久小说| 久久99精品久久久久久 | 亚洲va国产va天堂va久久| 久久www免费人成看片| 一本久久a久久精品综合香蕉|