2016-06-15 82 views
0

我正在開發我的GUI庫時使用C中的一堆結構。我很難決定如何初始化結構。這裏有兩種情況:當聲明或在單獨的函數中初始化結構

#define GUI_CreateBox(PageName,x,y,z,w,h,color) \ 
    struct GUI_BOX BoxName = {x,y,z,w,h,color} 

static void GUI_InitBox(struct GUI_BOX *box,uint32_t x, ... uint32_t color) 
{ 
    init code 
} 

我的問題是,哪一個會用最少的代碼空間?我覺得這個功能會更好。我想要使​​用這個定義,因爲它會比多次解除引用結構指針要快得多。我只是不明白結構的初始化如何工作,並希望在繼續之前得到第二個意見。

大家怎麼想?

還有一些背景信息。我將在ARM Cortex M-4設備上工作。我想要一個不錯的圖書館。

+0

最小的空間可能需要使用一個簡單的初始化程序,而不是根本不需要調用該函數,考慮到將所有字段傳遞給函數的開銷,該函數似乎除了將參數存儲到字段外別無它物。否則,你的問題太廣泛了。這不是討論論壇。 – Olaf

+0

嘗試兩種方法,看看哪些在實踐中最好(對於'最佳'的任何適當定義);它取決於更多的因素,而不是在這個層面上推理。 – Notlikethat

+0

推測,'PageName'參數和'BoxName'變量應該是一樣的(在宏初始化器中)。 –

回答

0

你會做這些特殊的初始化有多少?你會在這些初始化中做多少變化?這可能會影響你最少的代碼。哪些需要適用於全局(文件)範圍的變量?您可以在文件範圍使用宏;你不能在文件範圍使用函數 - 函數調用必須在函數體內進行,這也會導致關於「變量何時初始化」的問題。

注意的是,宏版本意味着你寫:

GUI_CreateBox(box1, 23, 45, 20, 30, 20, COLOUR_BLUE); 

但功能版本,意味着你可以寫:

struct GUI_Box box2; 
GUI_InitBox(&box2, 23, 45, 20, 30, 20, COLOUR_GREEN); 
…some code using box2… 
GUI_InitBox(&box2, 32, 54, 2, 3, 2, COLOUR_PURPLE); 
…more code using box2… 

這也讓你不初始化結構的一個選項;這可能不是一個好主意。

您的選擇。他們之間沒有太多的選擇。

你可能會考慮一個複合文字太:

#define GUI_INITBOX(x, y, z, h, w, c) \ 
    (struct GUI_BOX){ .x = (x), .y = (y), .z = (z), .h = (h), .w = (w), .color = (c) } 

然後你會寫:

struct GUI_BOX box1 = GUI_INITBOX(23, 45, 20, 30, 20, COLOUR_BLUE); 

聲明和初始化,你可以寫:

struct GUI_BOX box2; 
…code…; 
box2 = GUI_INITBOX(23, 45, 20, 30, 20, COLOUR_GREEN); 

到稍後分配(不初始化)box2。複合文字(和指定的初始化符)是C99的一部分,因此也是C11的一部分。

+0

我只需要初始化它們一次,但可能會有多達數百個這些對象。大多數結構與x,y,w,h和指針相同。我使用相似性來創建無效指針函數來移動東西。我對代碼大小很感興趣,我發現它增加了我的代碼。我不知道它到底是否會起作用,因爲初始化發生在一開始,所以也許我可以處理較慢的函數來初始化。 –

0

你必須考慮到你不打算初始化,但一次。就代碼大小而言,由於您的初始化例程只有賦值,因此宏將更小。此外,您不必使用函數調用,也不必傳入一堆或多個參數,因此可以節省堆棧大小以及吞吐量。

但你想考慮的一件事是有多少人會使用你的圖書館。當人們使用由許多宏組成的庫時,我遇到過很多次。沒有保護(參數類型檢查)您的參數,這可能會導致錯誤的對象初始化。

單就這一點,我總是寧可安全的一側,並用這樣一個函數內部,尤其是當你考慮到

雖然這並不適用於你的例子,如果你打算去在像宏這樣的函數中多次重複使用單個參數時,對於喜歡在參數中執行操作的用戶,您可能會得到一些意想不到的副作用。