2016-06-15 51 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

你必须考虑到你不打算初始化,但一次。就代码大小而言,由于您的初始化例程只有赋值,因此宏将更小。此外,您不必使用函数调用,也不必传入一堆或多个参数,因此可以节省堆栈大小以及吞吐量。

但你想考虑的一件事是有多少人会使用你的图书馆。当人们使用由许多宏组成的库时,我遇到过很多次。没有保护(参数类型检查)您的参数,这可能会导致错误的对象初始化。

单就这一点,我总是宁可安全的一侧,并用这样一个函数内部,尤其是当你考虑到

虽然这并不适用于你的例子,如果你打算去在像宏这样的函数中多次重复使用单个参数时,对于喜欢在参数中执行操作的用户,您可能会得到一些意想不到的副作用。