Как инициализировать все члены массива одним и тем же значением?

Или на реальном устройстве вы можете перейти в Настройки -> Мобильные сети -> Предпочтительные типы сетей и выбрать самый медленный доступный ... Конечно, это очень ограниченно, но для некоторых целей тестирования этого может быть достаточно.

897
задан Lundin 22 May 2017 в 06:47
поделиться

12 ответов

Если то значение не 0 (в этом случае, можно опустить некоторую часть инициализатора, и соответствующие элементы будут инициализированы к 0), нет никакого простого способа.

не пропускают очевидное решение, хотя:

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };

Элементы с отсутствующими значениями будут инициализированы к 0:

int myArray[10] = { 1, 2 }; // initialize to 1,2,0,0,0...

, Таким образом, это инициализирует все элементы к 0:

int myArray[10] = { 0 }; // all elements 0

В C++, пустой список инициализации также инициализирует каждый элемент к 0. Это не позволено с C:

int myArray[10] = {}; // all elements 0 in C++

Помнят, что объекты со статической продолжительностью хранения инициализируют к 0, если никакой инициализатор не будет определен:

static int myArray[10]; // all elements 0

И что "0" не обязательно означает "все-нуль битов", так использование вышеупомянутого является лучше и более портативным, чем memset (). (Значения с плавающей точкой будут инициализированы к +0, указатели на нулевое значение, и т.д.)

1165
ответ дан Community 22 May 2017 в 06:47
поделиться

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

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};
6
ответ дан warren 22 May 2017 в 06:47
поделиться

Можно сделать целую статическую вещь инициализатора, как детализировано выше, но это может быть настоящий лентяй, когда размер массива изменяется (когда массив embiggens, если Вы не добавляете соответствующие дополнительные инициализаторы, Вы получаете мусор).

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

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

12
ответ дан plinth 22 May 2017 в 06:47
поделиться

Вот иначе:

static void
unhandled_interrupt(struct trap_frame *frame, int irq, void *arg)
{
    //this code intentionally left blank
}

static struct irqtbl_s vector_tbl[XCHAL_NUM_INTERRUPTS] = {
    [0 ... XCHAL_NUM_INTERRUPTS-1] {unhandled_interrupt, NULL},
};

См.:

C-расширения

Обозначенный inits

Тогда задают вопрос: Когда можно использовать расширения C?

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

8
ответ дан Peter Mortensen 22 May 2017 в 06:47
поделиться
int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

я думаю, что это лучше, чем

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5...

, упаковывают размер изменений массива.

22
ответ дан Tarski 22 May 2017 в 06:47
поделиться

Я видел некоторый код, который использовал этот синтаксис:

char* array[] = 
{
    [0] = "Hello",
    [1] = "World"
};   

Где он становится особенно полезным, если вы создаете массив, который использует перечисления в качестве индекса:

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

#define _ITEM(x) [x] = #x

char* array[] = 
{
    _ITEM(ERR_OK),
    _ITEM(ERR_FAIL),
    _ITEM(ERR_MEMORY)
};   

Это поддерживает порядок, даже если вы пишете некоторые из перечисляемых значений не по порядку.

Подробнее об этой технике можно найти здесь и здесь .

49
ответ дан abelenky 22 May 2017 в 06:47
поделиться

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

int myArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

компилятор выведет размер из списка инициализатора. К сожалению, для многомерных массивов только наиболее удаленный размер может быть опущен:

int myPoints[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

в порядке, но

int myPoints[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

не.

62
ответ дан Frank Szczerba 22 May 2017 в 06:47
поделиться

Если массив, оказывается, интервал, или что-либо с размером интервала или размером Вашего шаблона мадам вмещает точное время в интервал (т.е. все обнуляет или 0xA5A5A5A5), лучший способ состоит в том, чтобы использовать memset () .

Иначе вызов memcpy () в цикле, перемещающем индекс.

5
ответ дан ddimitrov 22 May 2017 в 06:47
поделиться

Если Ваш компилятор является GCC, можно использовать следующий синтаксис:

int array[1024] = {[0 ... 1023] = 5};

Выезд подробно изложил описание: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html

375
ответ дан sth 22 May 2017 в 06:47
поделиться

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

#include <string.h> 

void array_init( void *start, size_t element_size, size_t elements, void *initval ){
  memcpy(        start,              initval, element_size              );
  memcpy( (char*)start+element_size, start,   element_size*(elements-1) );
}

// testing
#include <stdio.h> 

struct s {
  int a;
  char b;
} array[2][3], init;

int main(){
  init = (struct s){.a = 3, .b = 'x'};
  array_init( array, sizeof(array[0][0]), 2*3, &init );

  for( int i=0; i<2; i++ )
    for( int j=0; j<3; j++ )
      printf("array[%i][%i].a = %i .b = '%c'\n",i,j,array[i][j].a,array[i][j].b);
}

Результат:

array[0][0].a = 3 .b = 'x'
array[0][1].a = 3 .b = 'x'
array[0][2].a = 3 .b = 'x'
array[1][0].a = 3 .b = 'x'
array[1][1].a = 3 .b = 'x'
array[1][2].a = 3 .b = 'x'

РЕДАКТИРОВАТЬ: start + element_size изменено на (char *) start + element_size

-1
ответ дан 19 December 2019 в 20:21
поделиться

Для статической инициализации большого массива с одним и тем же значением без многократного копирования и вставки вы можете использовать макросы:

#define VAL_1X     42
#define VAL_2X     VAL_1X,  VAL_1X
#define VAL_4X     VAL_2X,  VAL_2X
#define VAL_8X     VAL_4X,  VAL_4X
#define VAL_16X    VAL_8X,  VAL_8X
#define VAL_32X    VAL_16X, VAL_16X
#define VAL_64X    VAL_32X, VAL_32X

int myArray[53] = { VAL_32X, VAL_16X, VAL_4X, VAL_1X };

Если вам нужно изменить значение, вы должны выполнить замену только в одном месте.

Изменить: возможные полезные расширения

(любезно предоставлено Джонатаном Леффлером )

Вы можете легко обобщить это с помощью:

#define VAL_1(X) X
#define VAL_2(X) VAL_1(X), VAL_1(X)
/* etc. */

Вариант можно создать с помощью:

#define STRUCTVAL_1(...) { __VA_ARGS__ }
#define STRUCTVAL_2(...) STRUCTVAL_1(__VA_ARGS__), STRUCTVAL_1(__VA_ARGS__)
/*etc */ 

, который работает со структурами или составными массивами .

#define STRUCTVAL_48(...) STRUCTVAL_32(__VA_ARGS__), STRUCTVAL_16(__VA_ARGS__)

struct Pair { char key[16]; char val[32]; };
struct Pair p_data[] = { STRUCTVAL_48("Key", "Value") };
int a_data[][4] = { STRUCTVAL_48(12, 19, 23, 37) };

имена макросов обсуждаются.

176
ответ дан 19 December 2019 в 20:21
поделиться

Слегка ироничный ответ; напишите оператор

array = initial_value

на своем любимом языке с поддержкой массивов (мой - Фортран, но есть много других) и свяжите его со своим кодом C. Вы, вероятно, захотите превратить это в внешнюю функцию.

6
ответ дан 19 December 2019 в 20:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: