• <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++ 第八碗 陳老C演迭代開發 潘小P學漸進編程(之三)

                 “啊……”小P舒服的伸著懶腰,“你知道什么是九三學社么?”
                 “?”
                 “就是上午睡到9點,下午睡到3點……舒服……”小P用手拍拍嘴,打了一個哈欠。
                 “呵呵,睡覺睡到自然醒,真是我們學生一大福利啊……”老C感嘆,“好了,閑話少說,你去開機……我去接水……”
                 “哦……”
                 兩人折騰一番后,終于坐在小P桌前。
                 “我們現在根據程序的模塊將它分成幾部分,我來寫,你看看。”老C開始在電腦鍵盤上扣扣扣扣的敲打起來,“我們的程序大體上分為三個主要部分,一個是 main()函數,這個是程序的進入點和主框架結構,負責算法部分;一個是我們的MY_DEBUG調試宏;再一個是我們的apple game游戲,提供接口供算法部分調用。根據這樣的劃分,每一個部分的規模和所擔負的責任就很清楚了。”老C一邊說,一邊在工程中添加了新的文件,并改寫 了main.c文件的內容。

            mydebug.h:

            #if !defined(MY_DEBUG_H_)
            #define MY_DEBUG_H_

            #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 */


            #endif /* MY_DEBUG_H_ */

            ------------------------------------------------------(華麗的分割線)

            applegame.h:

            #if !defined(APPLE_GAME_H_)
            #define APPLE_GAME_H_

            #define CHILDREN_NUM    20U

            typedef int SEAT_NUM;
            typedef enum tagEXISTE_STATE { ABSENT, EXISTED } EXISTE_STATE;
            typedef struct tagCHILD
            {
                SEAT_NUM        seatNum_;
                EXISTE_STATE    existeState_;
            }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;

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

            #endif /* APPLE_GAME_H_ */

            ------------------------------------------------------(華麗的分割線)

            applegame.c:

            #include "applegame.h"
            #include "mydebug.h"

            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;
            }


            ------------------------------------------------------(華麗的分割線)

            main.c:

            #include <stdio.h>
            #include "applegame.h"

            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;
            }

                 “編譯……運行……OK,我們的V0.03版本成功了……”老C道,他依照以前的辦法將各個新文件拷貝到AppleGame_V0.03目錄下,又新建了AppleGame_V0.04。 “我們的原則是盡量少的包含依賴關系。每個文件都包含且僅包含它們需要的頭文件,既不能多,也不能少。比如main.c,就算我知道 applegame.h中包含了stdio.h,但是并沒有明顯的線索和強烈的暗示告訴我applegame.h中一定包含stdio.h,所以我還是要 包含stdio.h,這樣就減小了main.c對applegame.h的一些依賴……如果哪天我一高興,決定不再在applegame.h中包含 stdio.h,這樣就可以少修改一些地方……偷懶,是程序員的美德……”
                 “嗯……”無視了老C的自吹自擂,小P看了幾遍工程中的文件,“嗯,這樣的確比寫在一起清晰很多。然后呢?”
                 “然后我們就繼續細化我們的代碼,你來接著寫啊。注意編碼的規范性……”老C答道。
                 “好!”小P開始挽袖子。
                 “不過在此之前我先教你一個乖。”老C將applegame.c文件打開,“你按一下Ctrl+Tab試試。”
                 “唔……哦?文本跳轉到了applegame.h?這個……好東東啊。”小P試了試。
                 “呵呵,你可以修改這個快捷鍵,我記得好像叫toggle head & source,因為某些惡趣味我改成了Alt+O,哈哈……”
                 “囧……”忽略過老C的傻笑,小P開始完善applegame.c文件。

                 經過一陣忙碌,小P修改了applegame.h和applegame.c文件。

            applegame.h:

            #if !defined(APPLE_GAME_H_)
            #define APPLE_GAME_H_

            #define CHILDREN_NUM    20U
            #define KICK_OUT_NUM    7U

            typedef int SEAT_NUM;
            typedef enum tagEXISTE_STATE { ABSENT, EXISTED } EXISTE_STATE;
            typedef struct tagCHILD
            {
                SEAT_NUM        seatNum_;
                EXISTE_STATE    existeState_;
            }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 kickOutNum_;
                int childrenRemained_;
                QUEUE childrenQueue_;
            }APPLE_GAME;

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

            #endif /* APPLE_GAME_H_ */

            ------------------------------------------------------(華麗的分割線)

            applegame.c:

            #include "applegame.h"
            #include "mydebug.h"

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

                game->currCountNum_      = 0;
                game->kickOutNum_        = KICK_OUT_NUM;
                game->childrenRemained_  = CHILDREN_NUM;

                game->childrenQueue_.size_  = CHILDREN_NUM;
                game->childrenQueue_.index_ = 0;
                for (i = 0; i < game->childrenQueue_.size_; ++i)
                {
                    game->childrenQueue_.queue_[i].seatNum_ = i + 1;
                    game->childrenQueue_.queue_[i].existeState_ = EXISTED;
                }
            }

            int IsGameOver(APPLE_GAME* game)
            {
                MY_DEBUG_1("The children remained %d\n", game->childrenRemained_);

                return (1 == game->childrenRemained_);
            }

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

                /* If the current child is existed in the queue, count on, then check if she will be kicked out. */
                if (EXISTED == game->childrenQueue_.queue_[game->childrenQueue_.index_].existeState_)
                {
                    /* Count on. */
                    game->currCountNum_++;

                    /* If the child counts kicked out number, then she is kicked out. */
                    if (game->currCountNum_ == game->kickOutNum_)
                    {
                        game->childrenQueue_.queue_[game->childrenQueue_.index_].existeState_ = ABSENT;
                        game->childrenRemained_--;
                        game->currCountNum_ = 0;

                        MY_DEBUG_1("The child kicked out is %d\n", game->childrenQueue_.queue_[game->childrenQueue_.index_].seatNum_);
                    }
                }
                
                game->childrenQueue_.index_++;
                game->childrenQueue_.index_ %= game->childrenQueue_.size_;
            }

            int LastChildSeatNum(APPLE_GAME* game)
            {
                int i;

                MY_DEBUG("Searching last child's seat number\n");

                for (i = 0; i < game->childrenQueue_.size_; ++i)
                {
                    if (EXISTED == game->childrenQueue_.queue_[i].existeState_)
                    {
                        break;
                    }
                }

                return game->childrenQueue_.queue_[i].seatNum_;        
            }

               “呵呵,代碼寫得還可以,但是程序執行結果到底對不對呢?”老C看著代碼問道,“你可以在applegame.h中將CHILDREN_NUM的值改為1U試試看邊界的情況,然后將CHILDREN_NUM的值改為3U,KICK_OUT_NUM的值改為2U,試試看調試輸出的內容是否正確。”
                 “好啊。”小P試著更改了幾下,看了看調試輸出內容和自己在紙上畫出的內容,“好像沒有什么不對,我又用5個小朋友和數到3被提出試了試,結果也是正確的。”
                 “OK,這么說我們的代碼經過你的測試是正確的啦,我們終于有了自己的第一個正式版本啦。”說完老C將所有文件拷貝到AppleGame_V0.04,然后又將AppleGame_V0.04重新命名為AppleGame_
            V1.00,“呵呵,這下你可以對比一下我們的V1.00版本和你原來的版本。”
                 “唔,現在的版本代碼變得多得多,但是……看起來更容易明白,而且比較容易調試和測試。”小P分析道。
                 “沒錯!代碼顯得多是因為增加了函數,因為問題的規模很小,所有我們這樣做有些麻煩——但這是練習——等我們熟悉了正規的做法再去進行直截了當的做法吧, 這樣基本功更扎實一些。”老C點頭,“我們再來優化一下applegame.c文件吧,因為里面的結構體點點點的看著實在是煩人。”他又建立了 AppleGame_V1.01目錄。
                 “唔,看著的確挺煩人的,那么你打算怎么優化么?”小P問。
                 “呵呵,把煩人的操作放到函數后面,這樣程序的結構和意圖會更加明顯。”老C回答。
                 “怎么做呢?”
                 “呵呵,您瞧好咧……”老C又開始敲鍵盤,優化applegame.c文件。

            applegame.c:

            #include "applegame.h"
            #include "mydebug.h"

            static void QueInitQueue (QUEUE* childQueue);
            static int QueIsChildExisted (QUEUE* childQueue);
            static void QueKickOutChild (QUEUE* childQueue);
            static void QueMoveToNextChild (QUEUE* childQueue);
            static int QueFindRemainedChild (QUEUE* childQueue);

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

                game->currCountNum_        = 0;
                game->kickOutNum_        = KICK_OUT_NUM;
                game->childrenRemained_    = CHILDREN_NUM;

                QueInitQueue(&(game->childrenQueue_));
            }


            int IsGameOver(APPLE_GAME* game)
            {
                MY_DEBUG_1("The children remained %d\n", game->childrenRemained_);

                return (1 == game->childrenRemained_);
            }

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

                /* If the current child is existed in the queue, count on, then check if she will be kicked out. */
                if (QueIsChildExisted(&(game->childrenQueue_)))
                {
                    /* Count on. */
                    game->currCountNum_++;

                    /* If the child counts kicked out number, then she is kicked out. */
                    if (game->currCountNum_ == game->kickOutNum_)
                    {
                        QueKickOutChild(&(game->childrenQueue_));
                        game->childrenRemained_--;
                        game->currCountNum_ = 0;

                        MY_DEBUG_1("The child kicked out is %d\n", game->childrenQueue_.queue_[game->childrenQueue_.index_].seatNum_);
                    }
                }
                
                QueMoveToNextChild(&(game->childrenQueue_));
            }

            int LastChildSeatNum(APPLE_GAME* game)
            {
                int seatNum;

                MY_DEBUG("Searching last child's seat number\n");

                seatNum = QueFindRemainedChild(&(game->childrenQueue_));

                return seatNum;
            }


            /************************************************************************/
            /* Local functions                                                      */
            /************************************************************************/
            static void QueInitQueue(QUEUE* childQueue)
            {
                int i;

                childQueue->size_    = CHILDREN_NUM;
                childQueue->index_ = 0;
                for (i = 0; i < childQueue->size_; ++i)
                {
                    childQueue->queue_[i].seatNum_ = i + 1;
                    childQueue->queue_[i].existeState_ = EXISTED;
                }
            }

            static int QueIsChildExisted(QUEUE* childQueue)
            {
                return (EXISTED == childQueue->queue_[childQueue->index_].existeState_);
            }

            static void QueKickOutChild(QUEUE* gameQueue)
            {
                gameQueue->queue_[gameQueue->index_].existeState_ = ABSENT;
            }

            static void QueMoveToNextChild(QUEUE* gameQueue)
            {
                gameQueue->index_++;
                gameQueue->index_ %= gameQueue->size_;
            }

            static int QueFindRemainedChild(QUEUE* gameQueue)
            {
                int i;
                
                for (i = 0; i < gameQueue->size_; ++i)
                {
                    if (EXISTED == gameQueue->queue_[i].existeState_)
                    {
                        break;
                    }
                }

                return gameQueue->queue_[i].seatNum_;    
            }

                 “編譯……運行……ok,我們的V1.01版本也好了。”老C又將所有文件拷貝到AppleGame_V1.01目錄下。
                 “等等,”小P問道,“我看不出有什么實質性的變化啊,無非就是用一些static函數替換了原來的內容,換湯不換藥啊。”
                 “呵呵,你看不出區別是因為你熟悉,如果你第一次看代碼,你會覺得是在代碼中看到
            QueMoveToNextChild(&(game->childrenQueue_))感 覺好些,還是看到一堆鬼畫符似的結構體點點點的感覺好?”老C解釋道,“意圖,這里強調意圖,因為使用了函數你一眼就可以看出程序執行的意圖,而如果是一 堆代碼的話,你還要反應半天;如果明白了意圖,再去看代碼,感覺會好很多——而且你可以根據代碼意圖提出更好的實現方法;同時這樣也減少了代碼中注釋的工 作量——一般在維護代碼的時候人們很少去修改注釋的;最后,如果你的具體實現需要被維護,這樣也給維護代碼的人提供了線索,無需他在源代碼程序中找來找 去……如果不小心還有可能將你的代碼進行錯誤的修改……”他找到水杯,喝了一大口,“總之不要害怕小而短的函數,有時它們對閱讀代碼的人來說是很好的伙 伴……”
                 “哦,有些道理。那么會不會影響程序執行的效率呢?”
                 “……會有一些,不過你要理解20-80原則……”
                 “什么是20-80原則?”小P問。
                 “就是說影響程序執行效率的代碼只占代碼總量的20%,我們如果要提高效率,需要把80%的經歷投放到這20%的代碼上——一般來說都是一些算法、方案上 的問題。換句話說,除非需要,否則不要進行效率優化——可維護性要高于效率——再說我們這樣做對效率的影響是微乎其微的。”
                 “哦,”小P點點頭,“為什么你的static函數命名這樣奇特?”
                 “唔……習慣。因為這些函數作用于Queue這個模塊,所以我使用Que作為前綴,表示函數屬于Queue模塊,然后采用動賓結構進行命名……習慣、習慣而已。”老C笑道。
                 “模塊?什么是模塊?”小P追問。
                 “呵呵,這個是我們下來需要討論的問題,和我們的V1.02版本有些關系。”老C說完又新建了一個AppleGame_V1.02的目錄。
                 兩人抬頭看看天色,已經接近黃昏了,于是老C決定暫停一下,“這個……我們還是先去喂腦袋吧……人是鐵……”
                 “呵呵,好吧,我知道一個東北菜館還不錯……我請,我請……”小P拍拍口袋。
                 “呵呵,總讓你請多不好意思,我請,我請……”兩人一邊推讓,一邊向門口走去。

            (V1.02還在后面喔)

            posted on 2009-02-04 22:10 Anderson 閱讀(2047) 評論(9)  編輯 收藏 引用

            評論

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

            羨慕小P,可以有朋友交流,促進,不像我們自學的這種,恩,慢慢琢磨  回復  更多評論   

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

            繼續力挺老C  回復  更多評論   

            # re: 第一桶 從C到C++ 第八碗 陳老C演迭代開發 潘小P學漸進編程(之三) 2009-02-05 11:18 yzb

            更著小P一起,
            和老C加油.
            挺啊,期待...  回復  更多評論   

            # re: 第一桶 從C到C++ 第八碗 陳老C演迭代開發 潘小P學漸進編程(之三)[未登錄] 2009-02-06 09:39 Sunny

            不錯.加油  回復  更多評論   

            # re: 第一桶 從C到C++ 第八碗 陳老C演迭代開發 潘小P學漸進編程(之三)[未登錄] 2009-02-06 22:16 Steven

            不錯,期待連載!  回復  更多評論   

            # re: 第一桶 從C到C++ 第八碗 陳老C演迭代開發 潘小P學漸進編程(之三) 2009-02-16 19:11 supersand

            兄弟,寫的不錯,繼續呀,等著呢。。。  回復  更多評論   

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

            好久沒出新的了,等的急啊 。。。  回復  更多評論   

            # re: 第一桶 從C到C++ 第八碗 陳老C演迭代開發 潘小P學漸進編程(之三) 2009-03-01 02:06 寶寶阿涕

            0.03版的main中怎么是include的applegame.h啊

            好像應該是applegame.c才對樣

            這個不錯哦,感覺復習一下C,大一只學了一點點,都忘了

            喜歡老C的教學方式啊  回復  更多評論   

            # re: 第一桶 從C到C++ 第八碗 陳老C演迭代開發 潘小P學漸進編程(之三) 2009-04-17 15:55 ty

            受教了,對博主的景仰之情如黃河之水滔滔不絕,希望博主繼續!  回復  更多評論   

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導航

            統計

            常用鏈接

            留言簿(6)

            隨筆檔案(21)

            文章檔案(1)

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            中文字幕精品久久久久人妻| 99久久免费国产精精品| 久久久久亚洲精品天堂久久久久久| 国产69精品久久久久99尤物| 亚洲国产小视频精品久久久三级| 99久久国产综合精品女同图片| 久久99国产综合精品| 91精品国产91久久久久久| 综合网日日天干夜夜久久| 99久久精品免费看国产| 欧洲人妻丰满av无码久久不卡| 99久久精品费精品国产| 看久久久久久a级毛片| 久久人人爽人人澡人人高潮AV | 国产综合成人久久大片91| 中文字幕无码精品亚洲资源网久久| 狠狠狠色丁香婷婷综合久久五月| 无码国内精品久久人妻麻豆按摩 | 精品久久人人爽天天玩人人妻| 青青草原综合久久大伊人| 青青草原1769久久免费播放| 一本色道久久HEZYO无码| 久久久久久一区国产精品| 免费观看成人久久网免费观看| 色综合久久无码五十路人妻| 久久久久久久波多野结衣高潮| 精品多毛少妇人妻AV免费久久| 2021精品国产综合久久| 国产精品久久久久久吹潮| 亚洲人成伊人成综合网久久久| 2020久久精品亚洲热综合一本| 久久久这里有精品中文字幕| 国产精品成人99久久久久| 国产精品VIDEOSSEX久久发布| 久久婷婷国产麻豆91天堂| 中文精品久久久久国产网址| 国产精品久久久久久久| 亚洲天堂久久精品| 国产精品美女久久久网AV| 欧美与黑人午夜性猛交久久久| 午夜精品久久影院蜜桃|