c語言的實踐技巧

來源:互聯網
上載者:User

看了《兩則c語言技巧》文章之後,很高興又學會了兩招用法!但是技巧畢竟還是要與實際應用相結合的,所以我下面就談一下我自己對這些技巧的看法,並貢獻自己發現的一下c

語言的用法。
1. Enum
    {
        FRUIT_APPLE,
        FRUIT_PEAR,
        FRUIT_BANANA,
        FRUIT_NR
    };

    int price[FRUIT_NR] = { [FRUIT_APPLE] = 20, [FRUIT_PEAR] = 25, [FRUIT_BANANA] = 30};
上面這種用法較常規用法的好處是不用來回移動數組內容,也更具有可讀性和修改性!一般我會將這種用法用在配置資料上,比如我們需要為一個下列框填值,但是顯示的值序列

還不確定,這種方式就很好的適應這種需求。如果擴充這種使用方式,可以用來類比一個設定檔的用途,這在嵌入式開發中是很有益的。

2. case的連用,雖然這種方式比較簡便但是犧牲了可修改性,除非非常確定不準備擴充中間case的處理,所以不建議使用。

c語言中還有其他的提示,我最近發現一個,使用結構體來封裝一個類似於c++中類的對象,使用結構體和函數指標相結合。
具體的使用看下面給出一個實現的迴圈隊列的實現。
在"cqueue.h"中如下定義

struct  tagAlgCycQueue;
typedef struct tagAlgCycQueue ALG_CYC_QUEUE;
typedef struct tagAlgCycQueue* PALG_CYC_QUEUE;

typedef  int (* CQ_IsFull) (PALG_CYC_QUEUE);
typedef  int (* CQ_IsEmpty) (PALG_CYC_QUEUE);
typedef  void (* CQ_InQueue) (PALG_CYC_QUEUE, void *);
typedef  void* (* CQ_OutQueue) (PALG_CYC_QUEUE);
typedef  int (* CQ_Reverse) (PALG_CYC_QUEUE);
typedef  void (* CQ_Jump)(PALG_CYC_QUEUE, int);

struct tagAlgCycQueue
{
    int nStartPos;
    int nCurPos;
    int nEndPos;
    int bInited;
    int nElementSize;
    int bDirect;
    int nLength;

    void* pBuf;

    /*
     * 注意這裡:用到前面的函數定義,通過這幾個函數定義,我們就可以實現自己的演算法,
     * 如果別人不滿意也可以從這裡修改來添加他自己的演算法實現。
     */
    CQ_IsFull  IsFull;
    CQ_IsEmpty IsEmpty;
    CQ_InQueue InQueue;
    CQ_OutQueue OutQueue;
    CQ_Reverse  Reverse;
    CQ_Jump     Jump;
};

這個函數用於初始化一個隊列結構
extern ALG_InitCycQueue(PALG_CYC_QUEUE pQueue,
                        int len, void *pBuf, int em_size);

在"cqueue.c"檔案中實現
#define _TEST_QUEUE(b) { \
                           if ( !(b) ) \
                           { \
                               printf("error: queue don't initialize!\n"); \
                               return -1; \
                           } \
                       }

 

static int ALG_CQ_IsFull(PALG_CYC_QUEUE pQueue)
{
    _TEST_QUEUE(pQueue->bInited);
    return ( ((pQueue->nEndPos + 1) % pQueue->nLength) == pQueue->nStartPos );   
}

static int ALG_CQ_IsEmpty(PALG_CYC_QUEUE pQueue)
{
    _TEST_QUEUE(pQueue->bInited);
    return ( ((pQueue->nStartPos + 1) % pQueue->nLength) == pQueue->nEndPos );
}

static int ALG_CQ_InQueue(PALG_CYC_QUEUE pQueue, void *pEm)
{
    _TEST_QUEUE(pQueue->bInited);
    if ( ALG_CQ_IsFull(pQueue) )
        return 0;

    if ( NULL == pEm )
    {
        memset(pQueue->pBuf+pQueue->nElementSize*pQueue->nEndPos, 0, pQueue->nElementSize);
    }
    else
    {
        memcpy(pQueue->pBuf+pQueue->nElementSize*pQueue->nEndPos, pEm, pQueue->nElementSize);
    }
    pQueue->nEndPos = (++pQueue->nEndPos) % pQueue->nLength;
    return 1;
}

static void* ALG_CQ_OutQueue(PALG_CYC_QUEUE pQueue)
{
    _TEST_QUEUE(pQueue->bInited);
    if ( ALG_CQ_IsEmpty(pQueue) )
        return NULL;
   
    pQueue->nStartPos = (++pQueue->nStartPos) % pQueue->nLength;
    return (pQueue->pBuf + pQueue->nElementSize*pQueue->nStartPos);
}

static void ALG_CQ_Jump(PALG_CYC_QUEUE pQueue, int offset)
{
    int i = offset;
   
    _TEST_QUEUE(pQueue->bInited);
    while ( i > 0 )
    {
        if ( ALG_CQ_IsFull(pQueue) )
        {
            ALG_CQ_OutQueue(pQueue);
        }
        ALG_CQ_InQueue(pQueue, NULL);
        i--;
    }  
}

/*
 * DESC: this function is used to initialize tagAlgDCycQueue struct, you must call
 *      this function when you want to use tagAlgDCycQueue object.
 *
 * IN  :pQueue      tagAlgDCycQueue point
 *      len         queue length
 *      pBuf        queue buffer
 *      em_size     the element size in queue
 *
 * RET : if success return 1, else return 0
 */
int ALG_InitCycQueue(PALG_CYC_QUEUE pQueue,
                                 int len, void* pBuf, int em_size)
{
    if ( NULL == pQueue || NULL == pBuf )
        return 0;

    pQueue->nLength = len;
    pQueue->nElementSize = em_size;
    pQueue->pBuf = pBuf;
    pQueue->nStartPos = 0;
    pQueue->nEndPos   = pQueue->nStartPos + 1;
    pQueue->nCurPos   = 0;
    pQueue->bInited   = 1;
    pQueue->bDirect   = 0;

    pQueue->IsEmpty   = ALG_CQ_IsEmpty;
    pQueue->IsFull    = ALG_CQ_IsFull;
    pQueue->InQueue   = ALG_CQ_InQueue;
    pQueue->OutQueue  = ALG_CQ_OutQueue;
    pQueue->Jump      = ALG_CQ_Jump;

    return pQueue->bInited;
};
這樣就可以實現一個比較原始的迴圈隊列的操作了,並且我們也對這個操作進行了一定的封裝。
但是以上的封裝還是有些問題,就是結構體內部的變數沒進行保護,呵呵,這個目前還沒有找到解決
方法。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.