c: макрос для инициализации нового объекта typedef'd - PullRequest
0 голосов
/ 18 июня 2020

Я определил новый тип:

#define MAX_ELEM 10
typedef struct my_type {
   int v[MAX_ELEM];
} my_type;

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

my_type m = MY_TYPE_INIT();

У меня могло бы быть что-то вроде этого:

#define MY_TYPE_INIT(m) \
   do { \
      int i;
      for (i = 0; i < MAX_ELEM; i++)  \
          m->v[i] = -1;
   } while (0)

Но я бы хотел инициализировать, как я показал ранее, присвоив значения непосредственно объекту типа my_type. Возможно ли это? Спасибо.

1 Ответ

2 голосов
/ 18 июня 2020

У меня могло быть что-то вроде этого:

#define MY_TYPE_INIT(m) \
   do { \
      int i;
      for (i = 0; i < MAX_ELEM; i++)  \
          m->v[i] = -1;
   } while (0)

Нет, не получилось. Упаковка его в макрос не позволяет вам помещать операторы do или for или исполняемые блоки в инициализатор.

Вы можете определять макросы, которые будут служить инициализаторами. Они даже могут быть функциональными. Но они должны расширяться до допустимых инициализаторов для того типа, с которым вы их используете.

Макросы нелегко выполнять подсчет или итерацию, особенно без верхней границы. Ваш самый чистый путь вперед - либо записать инициализатор и обновить его, если когда-либо MAX_ELEM изменения:

#define MY_TYPE_INIT { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }

// ...

my_type mt = MY_TYPE_INIT;

, либо написать функцию инициализации:

void init_my_type(my_type *mt) {
    for (int i = 0; i < MAX_ELEM; i++) {
        m->v[i] = -1;
    }
}

// ...

my_type mt;

// Note: must be inside a function:
init_my_type(&mt);
...