2013-12-20 62 views
2

我目前正在研究一個ZigBee WSNDemo項目,並且我被困在這部分代碼中。基本上,我必須在appInitMsgSender函數中將此宏用於隊列目的。使用MACROS隊列

void appInitMsgSender(void) 
{ 
    txState = APP_MSG_TX_FREE_STATE; 

    resetQueue(&appToSendQueue); 
    resetQueue(&appFreeQueue); 
    resetQueue(&appSentQueue); 
    resetQueue(&appDoneQueue); 

    for (uint8_t i = 0; i < ARRAY_SIZE(appTxBuffers); i++) 
    { 
     putQueueElem(&appFreeQueue, &appTxBuffers[i].next); 
    } 
} 

以上是應用程序的消息發送初始化函數。以下是使用它的宏。我想知道如何連接。我的意思是如何理解這段代碼的工作。

#define DECLARE_QUEUE(queue) QueueDescriptor_t queue = {.head = NULL,} 

// Type of queue element 
typedef struct _QueueElement_t 
{ 
    struct _QueueElement_t *next; 
} QueueElement_t; 

// Queue descriptor 
typedef struct 
{ 
    QueueElement_t *head; 
} QueueDescriptor_t; 

INLINE void resetQueue(QueueDescriptor_t *queue) 
{ 
    queue->head = NULL; 
} 

我真的很困惑,在這裏使用指針。我知道指針的工作原理和背後的理論。但在上述情況下,我感到困惑。

回答

0

該隊列使用稱爲linked list的數據結構實現。 QueueDescriptor_t包含一個指向列表中第一個QueueElement_t的指針。每個QueueElement_t包含一個指向列表中下一個QueueElement_t的指針。當QueueDescriptor_t指針爲NULL時,列表爲空。當QueueElement_t指針爲NULL時,它是列表中的最後一項。鏈接列表允許您創建項目集合,但項目不必在內存中連續(指針的next鏈接到集合中的下一個項目)。作爲比較,數組是的內存中連續的項目的集合(不需要next指針是必需的)。

3

這裏發生了什麼是很多抽象。基本上隱藏細節以使代碼的主體更具可讀性。當然,你需要明確地理解你頭腦中的所有基礎細節,以便讀懂你的意思。

要聲明一個隊列,將僅僅是:

DECLARE_QUEUE(appFreeQueue); 

如果我們擴展宏,這是一樣的文字:

QueueDescriptor_t appFreeQueue = {.head = NULL,}; 

如果我們再擴大QueueDescriptor_ttypedef,它會與寫作一樣:

struct appFreeQueue 
{ 
    QueueElement_t *head = NULL; 
}; 

如果我們展開QueueElement_ttypedef,我們可以看到,每一個元素指向另一個相同類型的元素:

struct appFreeQueue 
{ 
    typedef struct _QueueElement_t 
    { 
     struct _QueueElement_t *next = NULL; 
    } *head; 
}; 

但是,而不是要聲明一個隊列,每次寫出來,你可以只使用DECLARE_QUEUE宏來代替。這將以鏈表的形式創建一個空隊列。鏈接列表通常採用每個鏈接的形式,包含兩件事情,一些數據和一個指向下一個鏈接的指針。像這樣:

Element1    Element2    Element3 
[data][*Element2]-> [data][*Element3]-> [data][NULL] 

什麼是偉大的關於這就是你不必擋掉內存部分,當你開始,讓它空和未使用的,直到它被需要,就像您使用數組。相反,每個鏈接都可以在需要時動態分配,並且可以在指向上一個鏈接的內存中指向它的位置。

INLINE函數的作用與宏非常相似。在哪裏你看到resetQueue,在你的腦海中,你應該用它定義的功能來代替它。在這種情況下,它將第一個鏈接的next指針設置爲NULL,從而產生一個空隊列。

宏和INLINE函數之間略有差異。這些差異在這個問題的答案中詳細描述:Inline functions vs Preprocessor macros