Подтвердить что ты не робот

Инициализация массива ints

Есть ли у кого-нибудь способ инициализировать массив int (любой многобайтовый тип действительно прав), к ненулевому и не--1-значению просто? Под этим я имею в виду, есть ли способ сделать это в одном лайнере без необходимости делать каждый элемент отдельно:

int arr[30] = {1, 1, 1, 1, ...}; // that works, but takes too long to type

int arr[30] = {1}; // nope, that gives 1, 0, 0, 0, ...

int arr[30];
memset(arr, 1, sizeof(arr)); // That doesn't work correctly for arrays with multi-byte
                             //   types such as int

Просто FYI, используя memset() таким образом на статических массивах, дает:

arr[0] = 0x01010101
arr[1] = 0x01010101
arr[2] = 0x01010101

Другой вариант:

for(count = 0; count < 30; count++)
   arr[count] = 1;    // Yup, that does it, but it two lines.

У кого-нибудь есть другие идеи? Пока это C-код, никаких ограничений на решение. (другие библиотеки в порядке)

4b9b3361

Ответ 1

Это расширение GCC:

int a[100] = {[0 ... 99] = 1};

Ответ 2

for (count = 0; count < 30; count++) arr[count] = 1;

Одна строка.:)

Ответ 3

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

for(count = 0; count < 30 ; arr[count] = 1,count++);

Ответ 4

Единственный разумный способ сделать это во время инициализации (а не во время выполнения) выглядит следующим образом:

#define ONE1     1
#define FIVE1    ONE1, ONE1, ONE1, ONE1, ONE1
#define TEN1     FIVE1, FIVE1
#define TWENTY1  TEN1, TEN1
#define FIFTY1   TWENTY1, TWENTY1, TEN1
#define HUNDRED1 FIFTY1, FIFTY1

int array [100][4] =
{
  HUNDRED1,
  HUNDRED1,
  HUNDRED1,
  HUNDRED1
};

И далее, #define ONE2 2 и так далее. Вы получаете идею.

ИЗМЕНИТЬ: Причина, по которой я написал так много макросов, заключалась в том, чтобы продемонстрировать, насколько гибко это решение. Для этого конкретного случая вам не нужны все они. Но с такими макросами вы можете быстро и гибко написать любой список инициализаторов:

{
  FIFTY1, FIFTY2,  // 1,1,1,1... 50 times, then 2,2,2,2... 50 times
  TWENTY3, EIGHTY4 // 3,3,3,3... 20 times, then 4,4,4,4... 80 times
  ... // and so on
};

Ответ 5

В C вы обычно разрабатываете свою собственную "библиотеку поддержки" с помощью макросов, таких как

#define SET_ALL(a_, n_, v_)\
  do { size_t i, n = (n_); for (i = 0; i < n; ++i) (a_)[i] = (v_); } while(0)

#define SET_ALL_A(a_, v_) SET_ALL(a_, sizeof(a_) / sizeof *(a_), v_)
#define ZERO_ALL(a_, n_) SET_ALL(a_, n_, 0)
#define ZERO_ALL_A(a_) SET_ALL_A(a_, 0)

а затем используйте их в своем коде как

int arr[30];

SET_ALL_A(arr, 1);

Ответ 6

Одна строка с указателями!

for (int *p = a; p < (a + 30); p++) *p = 1;

Или если вы преждевременно боитесь удара производительности, вызванного многократным вычислением (a + 30):

for (int *p = a + 30 - 1; p >= a; p--) *p = 1;

Ответ 7

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

int arr[30] = {1, 1, 1, 1, ...}; 

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

Иногда инициализация более динамична, как в этом примере:

int arr[30];
int x = fetchSomeValue();
for(int i=0; i<30; i++) arr[i] = x;

В этих случаях вам нужно закодировать его, а общее правило - максимизировать читаемость, а не сводить к минимуму ввод текста. Этот код будет записан один раз и прочитан много раз.