2016-06-15 2 views
0

Я работаю с кучей структур в 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 и указателями. Я использовал сходство для создания функций указателей void для перемещения вещей. Я большой по размеру кода, и я обнаружил, что он увеличил мой код. Я не знаю, будет ли это иметь значение в конце, потому что инициализация происходит в начале, поэтому, возможно, я могу справиться с более медленной функцией для инициализации. –

0

Вы должны учитывать тот факт, что вы не собираетесь инициализировать, но один раз. Что касается размера кода, так как ваша процедура инициализации имеет ТОЛЬКО назначения, макрос будет меньше. Также с тем фактом, что вам не нужно использовать вызов функции или передавать кучу или аргументы, вы сохраняете размер стека, а также свою пропускную способность.

Но главное, что вы хотели бы рассмотреть, это то, сколько человек будет использовать вашу библиотеку. Я столкнулся с этим довольно много раз, когда люди используют библиотеки, которые состоят из множества макросов. Для ваших аргументов нет защиты (проверка типа параметра), что, очевидно, может привести к инициализации плохих объектов.

только для этой точки, я всегда заблуждаться на стороне безопасности и пойти с делать это внутри функции, особенно если учесть, что

И хотя это не относится к вашему примеру, если вы планируете при повторном использовании одного параметра несколько раз в такой функции, как макрос, вы можете получить некоторые неожиданные побочные эффекты для людей, которые предпочитают делать операцию в аргументе.

Смежные вопросы