2016-12-30 3 views
3

Для структуры, какКак инициализировать сразу несколько структурных переменных?

struct data{ 
    int a; 
    int b; 
    int c; 
}; 

как можно инициализировать несколько экземпляров этой структуры с одинаковыми значениями сразу?

Вместо:

struct data object1 = {0,0,0}, object2 = {0,0,0}, object3 = {0,0,0}; 
+3

Что означает «идентичные значения»? Может ли это означать '{1,2,3}' для всех объектов или только '{0,0,0}' всегда? – Gerhardh

+0

Инициализация всех полей в 'int 0' - это одно. Инициализация на ненулевые «идентичные значения» - это другое. Какая цель? – chux

+0

См. [Инициализация диапазона C-массива] (http://stackoverflow.com/q/7803861/2410359) – chux

ответ

3

как я могу инициализировать несколько экземпляров этой структуры с одинаковыми значениями сразу?

Не совсем «сразу», что бы это означает, иметь в виду, но, по крайней мере, не повторяя себя (то есть следующий the DRY-principal) вы могли бы сделать:

int main(void) 
{ 
    struct data object1 = {1, 2, 3}, object2 = object1, object3 = object1; 

    ... 
} 

или с каждым определением на отдельная строка:

int main(void) 
{ 
    struct data object1 = {1, 2, 3}; 
    struct data object2 = object1; 
    struct data object3 = object1; 

    ... 
} 
+0

Спасибо, среди всех хороших предложений, ваши призывы ко мне больше всего нравятся. – Creatronik

4

Вы можете взять массив struct с и использовать одну фигурную скобку огороженного инициализатору, как

struct data object [3] = {0}; 

идет несколько переменных этого типа структуры , все инициализируются до 0 (или эквивалент).

Это делает использование особого свойства инициализации, цитирует C11, глава

Инициализация должны происходить в списке инициализатора порядке, каждый инициализатор предусматривало частностей подобъекта отвергая любой ранее перечисленный инициализатор для того же подобъект ; 151) все подобъекты, которые не инициализированы явно, должны быть неявно инициализированы так же, как объекты , имеющие статическую продолжительность хранения.

и инициализации для объектов, имеющих static хранение,

[...] Если объект, который имеет длительность статического или потока хранения не инициализируется явно, то:

- если он имеет тип указателя, он инициализируется нулевым указателем;

- если у него арифметический тип, он инициализируется (положительным или без знака) нулем;

- если он является агрегатом, каждый элемент инициализируется (рекурсивно) в соответствии с этими правилами, , и любое заполнение инициализируется нулевыми битами;

- если это объединение, первый именованный элемент инициализируется (рекурсивно) в соответствии с этими правилами , и любое заполнение инициализируется нулевыми битами;

Это означает, что если вы не хотите, чтобы все значения были инициализированы до 0, существуют альтернативные способы. Как упоминалось в other answer г-ном Джонатаном Рейнхартом, вы можете использовать назначенные инициализаторы.

+0

Приятный и короткий, но только если все данные должны быть установлены на 0. Для более общего смысла «одинаковых значений» это не сработает. – Gerhardh

+0

@ Герхард только если .... не то, что критерии в вопросе? –

+0

Возможно, может и нет. В текстовой части это ограничение отсутствует. Я предполагаю, что этот пример является лишь плохим. Если бы он хотел иметь все это, то он, вероятно, сказал бы нам прямо, вместо того, чтобы использовать общую «идентичную стоимость». – Gerhardh

4

Во-первых, я предпочитаю стиль ядра Linux и предпочитаю designated initializers.

Я бы сделал то, что они делают, и создайте макрос для инициализации вашей структуры. Это упрощает добавление элементов и управление их инициализацией.

struct data { 
    int a; 
    int b; 
    int c; 
}; 

#define INIT_DATA { \ 
    .a = 0, \ 
    .b = 0, \ 
    .c = 0, \ 
} 

И использовать его как это:

struct data mydata = INIT_DATA; 

Продолжая стиль Linux, вы бы не более чем одна из этих переменных на линии в любом случае. Это облегчает просмотр, когда переменные добавляются/удаляются. Что случилось с:

struct data old_data = INIT_DATA; 
struct data new_data = INIT_DATA; 

Если у вас более пары, должны ли они быть отдельными переменными или они должны быть массивом? Если да, то вы можете воспользоваться расширением GNU, чтобы инициализировать диапазон:

struct data datas[N] = { 
    [0 ... N-1] = INIT_DATA, 
}; 

В противном случае, вам нужно будет использовать обычный старый цикл, чтобы инициализировать данные во время выполнения.

+0

Наконец, он получил часть инициализации диапазона с использованием расширения GNU. –

+2

Я не знаком с расширением GNU, но '[0 ... N]' выглядит неправильно. Является ли это указание элементов '0,1,2 ... N' (' N + 1' элементов) для массива 'N'? (слишком много) – chux

+0

@JonathonReinhart Теперь это намного лучше, вверх. Кроме того, процитировал ссылку на ваш ответ в моей. :) –

0

Создайте массив структур и инициализируйте их в цикле.

struct data array[N_ITEMS]; 

for(i=0; i<N_ITEMS; i++) 
{ 
    array[i].a=a; 
    array[i].b=b; 
    array[i].c=c; 
} 

Если вы хотите инициализировать все поля в 0, вы можете использовать MemSet:

memset(array, 0, sizeof(array)); 
+1

* «Если вы хотите инициализировать все поля одним и тем же значением, вы можете использовать memset». * Это ** опасный ** совет, поскольку memset работает только с байтами, поэтому его можно использовать только для инициализации всего объекта нулями. –

+0

@ JonathonReinhart, вы правы.Хотя в этом случае, если он хотел бы начать с некоторой экзотической ценности (например, -1), он все равно мог использовать memset. – goncalofr

+0

Хотя вы технически верны, такой хакерство никогда не пройдет через обзор кода, поскольку это наземная мина. –