青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

第一桶 從C到C++ 第六碗 陳老C演迭代開發 潘小P學漸進編程(之一)

     “今天早上陽光明媚啊,”老C在教研室門口深呼吸。

     “嗯,東花園顯得很漂亮啊……”小P應聲道,兩人走過東花園,來到教研室,準備妥當后,坐在小P桌前。

     “好,我們今天先不評論你的代碼內容,而是重新來寫這個代碼。”老C不好意思說小P的代碼太爛以至于無法評審,所以決定另起爐灶,“然后我們拿新寫的這個版本與原來的版本做比較。”

     “也好。”小P同意。

     “這樣,我們兩個來一起寫這個代碼,這樣更快一些。”老C道。

     “好啊好啊。”

     兩人新建了一個名叫AppleGame的工程,然后老C添加了一個main.c的文件,“本來在這里應當使用配置管理工具的,但是因為簡單起見,我們就土 法煉鋼,采用拷貝的方法記錄版本吧。”老C一邊說一邊在硬盤上建立了一個新目錄,起名為AppleGame_V0.01,“名字也隨便起了,不用使用 VBD等等復雜的規范,但是你千萬注意這只是例子,以后千萬不要隨便學啊。”老C解釋道,“至于什么配置管理和版本命名規范,我們以后再說。”

     “槑……”小P有些暈,下意識的回答道。

     “我們的做法在一般面試、筆試的時候可千萬不要用,完全是大炮打蚊子……在這里出現只是為了演示,然而如果你熟悉了這樣的開發過程,再反過來使用更直接的方法應付面試和筆試還是比較容易的,”老C又補充道,“大炮一響,黃金萬兩……有時打打大炮也是有價值的,起碼熟悉了開炮過程,這樣以后用大炮打黃金就駕輕就熟了……”

     “……”小P決定無視老C的自言自語,心想人上了年紀就是有些羅嗦。

     “好,第一個任務,寫一個main函數。”

     “這個簡單。”小P應道。在文件上敲下幾行代碼。


void main()
{
}

     “唉,這樣是有問題滴……”老C說到。

     “什么問題?”

     “規范……”老C回答,“我們應當這樣寫。”老C開始更改小P的代碼。


int main()

{

    return 0;

}

int main(int argc, char* argv[])

{

    return 0;

}


     “我們兩個中間選一個,因為這個程序沒有命令支持,所以就第一個吧。”老C說到,“這個是C99的新標準,我們還是按照標準來吧。”老C補充道,“你可以 在學校圖書館查查《ISO/IEC 9899 : 1999》這個文檔,里面說的很清楚。如果我們還使用原來的格式,可能在代碼兼容性上會出問題,我們寫出的代碼就不能在所有編譯器上編譯通過……”

     “是么?這么復雜……”小P有些疑惑,“好吧,那么就這樣吧。”

     “那么現在說說你解決這道題的思路吧。”老C問。

     “嗯,先設計一個循環隊列,每個隊列中的元素表示一個小朋友,1表示在對列中,0表示他不在對列中,然后開始按照規則玩游戲,直到剩下最后一個小朋友,然后在隊列中找出這個剩下的元素,打印它的下標……就是座位號碼啦……”

     “嗯,思路還算清晰,”老C評論,“我們姑且不論選擇循環隊列是否合適,就先按照這個思路來做,等到后面再評審更改吧。”然后他在文件中添加如下的語句。


int main()
{
    /* Initialize the queue. */

    /* Play the game, until the last one is found. */

    /* Search the last one's seat number.  */

    return 0;
}

     “好了,我們的第一版程序完成了。”老C拍拍手。
     “完了?”小P有些不敢相信。
     “是啊,”老C確定的說,“編程不只是寫代碼,代碼 != 程序!當你開始進行思考的時候,就開始進行程序設計了,代碼不過是程序的表達方式。如果人類的語言可以在計算機上執行,你剛才說的話,就是代碼。是不是這樣?”
     “嗯,有些道理……”
     “編譯!好了,我們的第一版程序沒有什么問題!”老C說完,將main.c文件拷貝到AppleGame_V0.01文件夾下面,然后又新建了一個AppleGame_V0.02的文件夾。
     “下來我們需要一個調試宏,”老P說到,“本來可以使用IDE為我們準備的debug和release編譯選項,但是這里我們先不用,為了明白背后的道理,我們完全自己打造一個先。關于debug和release,我們以后再說。”
     “哦……”小P點點頭。
     老C在main.c的開頭寫下如下代碼。

#include <stdio.h>

#define PRINT_DEBUG_INFO


#if defined(PRINT_DEBUG_INFO)
#define MY_DEBUG(str)            printf(str)
#define MY_DEBUG_1(str, par)    printf(str, par)
#else
#define MY_DEBUG(str)
#define MY_DEBUG_1(str, par)
#endif // PRINT_DEBUG_INFO

     “這幾個宏用于在調試的時候輸出一些中間信息,”老C解釋道,“如果我們想輸出調試信息,只需要#define PRINT_DEBUG_INFO就可以了,否則就注釋掉這個宏。這只是一些小技巧而已,沒有什么神秘的。”
     “是嗎?嗯,我看看……”小P琢磨著代碼。
     “下來進行一些實質性的,”老C接著說,“但是之前我們要了解一個規則,用問題域的詞匯去編程,而不是解決域。”
     “槑,什么叫問題域?解決域?”小P不解。
     “我寫你看好了。”老C說道,然后在main.c文件中接下來的部分寫下如下內容。

//////////////////////////////////////////////////////////////////////////
//
#define CHILDREN_NUM    20U

typedef int SEAT_NUM;
typedef enum tagEXIST_STATE { ABSENT, EXISTED } EXIST_STATE;
typedef struct tagCHILD
{
    SEAT_NUM       seatNum_;
    EXIST_STATE    existState_;
}CHILD;

#define QUEUE_LENGTH    CHILDREN_NUM
typedef CHILD QUEUE_CONTENT;
typedef struct tagQUEUE
{
    int size_;
    int index_;
    QUEUE_CONTENT queue_[QUEUE_LENGTH];
}QUEUE;

typedef struct tagAPPLE_GAME
{
    int currCountNum_;
    int childrenRemained_;
    QUEUE childrenQueue_;
}APPLE_GAME;

void InitAppleGame (APPLE_GAME* game);
int IsGameOver (APPLE_GAME* game);
void PlayGame (APPLE_GAME*  game);
int LastChildSeatNum (APPLE_GAME* game);



//////////////////////////////////////////////////////////////////////////
//
int main()
{
    APPLE_GAME theGame;
    int num;
    
    /* Initialize the game. */
    InitAppleGame(&theGame);

    /* Play the game, until the last child is found. */
    while (!IsGameOver(&theGame))
    {
        PlayGame(&theGame);
    }

    /* Search the last child's seat number.  */
    num = LastChildSeatNum(&theGame);

    printf("The last child's seat number is %d.\n", num);

    return 0;
}



//////////////////////////////////////////////////////////////////////////
//
void InitAppleGame(APPLE_GAME* game)
{
    MY_DEBUG("Init the apple game.\n");
}

int IsGameOver(APPLE_GAME* game)
{
    static int n = -1;
    
    MY_DEBUG("Only one child?\n");
    ++n;

    return n;
}

void PlayGame(APPLE_GAME* game)
{
    MY_DEBUG("Play game...\n");
}

int LastChildSeatNum(APPLE_GAME* game)
{
    int n = 1;
    MY_DEBUG("Searching last child's seat number\n");

    return n;
}

     “喏,就是這個意思,盡量用現實生活的語言對需要解決的問題進行描述,并將關系相近的變量用結構體放在一起。”老C說,“然后將對這些名詞的操作寫成可以 用現實生活語言表達的函數,并將結構體作為函數的入口參數傳入函數中。”老C咽了一口唾沫,“咳咳,你再比較比較我們這兩版的注釋有什么變化?”
     “叫我看看……”小P開始比較代碼,“哦,在這個版本你用 game 代替了 queue,用 child 代替了 one, 但是有什么實質區別?”小P有些不解。
     “嗯,這個是一個用問題域詞匯編程而不是解決域詞匯編程的例子,最大的優點是意圖明確,容易理解,代碼可讀性強;另外一個好處是相對穩定——比如用 game 代替 queue——其一,評審代碼的人可能會不明白這個queue是做什么的,為什么和下面的初始化函數格格不入,從而造成你頻繁的回答大量的溝通性的問題, 這將大大影響你生活的穩定性和質量;其二,如果我們將來——我是說如果——使用list數據結構來替換queue,避免了還要更改注釋的風險——代碼更新 而注釋陳舊,正是我們在進行項目開發時一個特別特別特別的n次冪嚴重的問題……而使用問題域的詞匯,只要需求不發生變更,則我們就不需要修改什么而導致一 些……代碼人格上的分裂……”
     “哦,我再消化消化……”小P開始看代碼,“下面這些函數的實現是什么意思?”
     “嗯,是測試,”老C說,“我們先不看具體函數,先看看main()函數的主要結構。”

int main()
{
    APPLE_GAME theGame;
    int num;
    
    /* Initialize the game. */
    InitAppleGame(&theGame);

    /* Play the game, until the last child is found. */
    while (!IsGameOver(&theGame))
    {
        PlayGame(&theGame);
    }

    /* Search the last child's seat number.  */
    num = LastChildSeatNum(&theGame);

    printf("The last child's seat number is %d.\n", num);

    return 0;
}

     “我們用實際的代碼完善剛才的注釋——剛才的注釋其實就是偽代碼的一部分——然后在框架函數中加入測試代碼,檢驗我們的算法是否可行。”老C解釋道,“現在我們的算法一目了然,你看看是否是用問題域的詞匯表達算法更清晰一些呢?比一些a,b,c之類,或者其類似的解決域內的名字更好理解吧?”
     “哦,我再看看……”小P答道,“我要消化一下……”
     “嗯,”等小P抬起頭,老C補充道,“接下來一個重要的規則是先構思如何測試,更先于編碼!”
     “稍等,”可能被新的信息灌輸的有些頭暈,“這個是什么意思?”小P有些反應不過來。
     “就是說,在編碼之前,我們要先想好如何測試我們即將要編寫出來的代碼。我們的代碼是否易于被測試,關系到我們代碼質量的生命!”老C解釋道,“如果你一 開始就考慮到這些問題,并留有充分的余地,那么在做代碼自測和測試人員測試時,會節省組織內部大量的精力……算了,這些也是要靠編寫代碼的規模積累起來的 經驗,你以后會慢慢的明白的。但是,無論如何你在編寫代碼的時候要保持足夠的意識,要不斷提醒自己,我所寫的代碼易于測試嗎?”
     “好,我記住了。”小P說。
     “呵呵,其實經歷了一些挫折你才會真正明白——不過就算建立了概念也不錯。”老C笑道,“現在你編譯并運行一下代碼吧,觀察一下屏幕輸出的信息……”
     “好,”小P看了看文件底部的函數實現,然后又看了看屏幕輸出信息,“哦,算法的脈絡這樣看就比較清楚了,果然我腦海中就是這么想的,不過現在更具體,也好追蹤了。”
     “O.K.!我們第二版的程序又有了!”
     “這么快?為什么?”小P不解道。
     “我們驗證了算法,證實算法框架運行與設計——就是你腦海中的步驟——是一致的,這樣當然ok了!”老C一邊說一邊將main.c拷貝到AppleGame_V0.02,并且又新建了一個AppleGame_V0.03目錄。

(請等待V0.03版本)

posted on 2009-01-23 03:36 Anderson 閱讀(1778) 評論(6)  編輯 收藏 引用

評論

# re: 第一桶 從C到C++ 第六碗 陳老C演迭代開發 潘小P學漸進編程(之一)[未登錄] 2009-01-23 12:40 Len

看來更新的速度很快呀,又要結冊出版了  回復  更多評論   

# re: 第一桶 從C到C++ 第六碗 陳老C演迭代開發 潘小P學漸進編程(之一)[未登錄] 2009-01-23 16:45 ypp

非常不錯,原創作品,極力支持  回復  更多評論   

# re: 第一桶 從C到C++ 第六碗 陳老C演迭代開發 潘小P學漸進編程(之一) 2009-01-23 17:22 winsty

現在用純C開發的機會太少了吧
個人覺得某些規范在OOP下并不合適  回復  更多評論   

# re: 第一桶 從C到C++ 第六碗 陳老C演迭代開發 潘小P學漸進編程(之一) 2009-01-23 23:55 imnobody

真的很棒,i like  回復  更多評論   

# re: 第一桶 從C到C++ 第六碗 陳老C演迭代開發 潘小P學漸進編程(之一) 2009-02-04 00:24 zoujer

此章學到很多東西,期待更精彩的~~~~~  回復  更多評論   

# re: 第一桶 從C到C++ 第六碗 陳老C演迭代開發 潘小P學漸進編程(之一) 2009-02-04 09:03 tmhlcwp

之前在"C++博客"上有看到過同風格的博文,但現在找不到了,有誰知道的告訴下哈,謝謝了  回復  更多評論   


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2025年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

導航

統計

常用鏈接

留言簿(6)

隨筆檔案(21)

文章檔案(1)

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲电影在线看| 亚洲香蕉网站| 亚洲综合成人在线| 国产精品大全| 中文一区二区在线观看| 亚洲国产精品第一区二区三区 | 国产亚洲网站| 久久精品一本| 欧美一区二区成人| 在线观看欧美精品| 欧美伦理91i| 一本色道久久综合亚洲精品婷婷 | 久久一区免费| 久久激情视频免费观看| 亚洲二区在线| 日韩一级片网址| 国产精品午夜av在线| 香蕉国产精品偷在线观看不卡 | 欧美大片在线影院| 欧美搞黄网站| 午夜精品美女久久久久av福利| 欧美一区二区三区四区高清| 欲色影视综合吧| 亚洲美女精品一区| 国产精品免费久久久久久| 久久免费黄色| 欧美激情国产日韩精品一区18| 亚洲一区影音先锋| 欧美一区二区在线播放| 最新国产成人在线观看| 野花国产精品入口| 黑人极品videos精品欧美裸| 欧美激情精品久久久久久大尺度| 欧美日韩一区视频| 久久免费国产精品| 国产精品高潮视频| 另类专区欧美制服同性| 欧美久久久久| 久久久久**毛片大全| 欧美精品亚洲二区| 久久福利电影| 欧美日韩中文字幕综合视频| 葵司免费一区二区三区四区五区| 欧美精品一区二区三区蜜臀 | 亚洲日韩中文字幕在线播放| 亚洲在线一区| 99精品视频免费观看视频| 欧美性做爰猛烈叫床潮| 国产美女高潮久久白浆| 亚洲大片av| 国产亚洲成人一区| 亚洲国产精品久久久久秋霞蜜臀| 国产精品久久国产精品99gif| 欧美18av| 国产乱肥老妇国产一区二| 亚洲第一在线综合网站| 韩国成人理伦片免费播放| 99视频一区二区三区| 亚洲精品美女在线观看| 欧美中文日韩| 香蕉久久夜色精品| 欧美日韩伦理在线| 欧美激情欧美狂野欧美精品| 极品裸体白嫩激情啪啪国产精品| 日韩亚洲在线观看| 日韩一级成人av| 欧美激情成人在线视频| 亚洲国产婷婷综合在线精品| 亚洲韩日在线| 美女啪啪无遮挡免费久久网站| 久久欧美中文字幕| 国产综合网站| 久久成人精品电影| 欧美亚洲综合网| 国产欧美日韩视频一区二区| 亚洲在线国产日韩欧美| 在线亚洲免费视频| 欧美区在线观看| 亚洲人成网站777色婷婷| 激情欧美一区二区| 美女日韩欧美| 99国内精品久久久久久久软件| 最新国产精品拍自在线播放| 欧美成人资源网| 日韩视频专区| 欧美一区=区| 国产在线精品自拍| 老司机精品久久| 欧美福利在线| 日韩一级视频免费观看在线| 欧美揉bbbbb揉bbbbb| 一本色道久久综合亚洲精品高清| 亚洲欧美另类在线| 国产色综合天天综合网| 久久激情五月婷婷| 亚洲高清视频在线| 亚洲激情视频网站| 欧美日韩专区在线| 午夜天堂精品久久久久| 久久全球大尺度高清视频| 国产日本欧美一区二区三区| 欧美在线三级| 蜜臀av性久久久久蜜臀aⅴ| 91久久精品国产91久久| 欧美精品一区二区三区视频| 一本色道婷婷久久欧美| 国产精品久久久久久久第一福利| 亚洲国产高清在线观看视频| 午夜精品三级视频福利| 激情综合色综合久久| 亚洲免费观看| 国产裸体写真av一区二区| 亚洲三级国产| 欧美喷水视频| 亚洲人成小说网站色在线| 欧美激情一区二区在线| 国产一区视频网站| 日韩视频一区二区在线观看| 国产美女一区二区| 亚洲精品1区| 午夜老司机精品| 欧美色精品天天在线观看视频 | 欧美成人亚洲| 亚洲性视频网站| 欧美r片在线| 美女啪啪无遮挡免费久久网站| 男女av一区三区二区色多| 久久九九热免费视频| 久久综合99re88久久爱| 国产日韩精品综合网站| 女人天堂亚洲aⅴ在线观看| 国产亚洲人成网站在线观看| 亚洲第一在线视频| 亚洲图片欧洲图片av| 亚洲美女av黄| 国产精品网站在线播放| 久久久久久久尹人综合网亚洲| 每日更新成人在线视频| 国产精品视频观看| 欧美精品福利视频| 亚洲综合国产| 久久精品在线免费观看| 99国产精品久久久久久久| 欧美a级一区二区| 国产精品xxxav免费视频| 亚洲欧美在线看| 久久久一二三| 欧美亚洲一区二区在线| 欧美黄色免费| 欧美激情一二三区| 在线观看不卡| 亚洲一二区在线| 好看的亚洲午夜视频在线| 欧美丰满高潮xxxx喷水动漫| 欧美成人精品h版在线观看| 亚洲图片激情小说| 午夜老司机精品| 亚洲男人的天堂在线观看 | 欧美日本视频在线| 欧美一级淫片aaaaaaa视频| 免费一级欧美片在线观看| 久久久久一区二区| 一区二区三区国产在线观看| 久久9热精品视频| 免费在线日韩av| 国产一区二区黄| 亚洲视屏一区| 午夜精品免费视频| 欧美体内谢she精2性欧美 | 欧美成人亚洲成人日韩成人| 久久免费视频这里只有精品| 久久久一区二区| 久久久久久亚洲精品杨幂换脸| 亚洲欧美制服另类日韩| 亚洲国产小视频| 久久精品国产99国产精品澳门| 亚洲国产日韩一区二区| 欧美另类极品videosbest最新版本| 亚洲精品综合在线| 99精品国产在热久久婷婷| 久久婷婷综合激情| 欧美成人一区二区三区| 1000精品久久久久久久久| 久久手机精品视频| 亚洲精品欧洲| 欧美在线播放| 亚洲激情在线观看视频免费| 国产区亚洲区欧美区| 欧美专区福利在线| 欧美激情一区二区在线| 亚洲图中文字幕| 亚洲午夜一区二区三区| 中日韩美女免费视频网址在线观看| 亚洲欧美99| 亚洲韩国青草视频| 亚洲电影免费观看高清| 亚洲国产精品ⅴa在线观看 | 欧美激情中文不卡| 亚洲综合99| 国产精品成人国产乱一区|