Инициализация многомерного массива с одним значением - PullRequest
4 голосов
/ 11 апреля 2011

Может ли кто-нибудь напомнить мне о синтаксисе присвоения массива в C, в частности многомерного, единственному значению?

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

int ArrayName [5][5] = {1};

для инициализации массива равным 1.

Ответы [ 4 ]

6 голосов
/ 11 апреля 2011

В языке C нет компактного синтаксиса, который бы инициализировал все элементы массива одним значением, независимо от того, является ли массив многомерным или одномерным.Существует синтаксис, который устанавливает все элементы на ноль (а это = { 0 }), но для любого другого значения это невозможно.

Конечно, вы можете прописать отдельные инициализаторы для всех элементов массива, но это, вероятно, не то, что вы ищете.

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

1 голос
/ 11 апреля 2011

Многомерные массивы могут быть построены динамически, используя указатели на указатели с malloc. В приведенном ниже примере, один указатель на указатель на int объявлен. После объявления Указатель не имеет значимого значения. Затем вызов Mallac просит указатель указывает на блок из nx действительных единиц памяти:

x =  (int **) malloc(nx * sizeof(int *));

После этого вызова x теперь имеет допустимое значение; в частности, начальный адрес блока памяти, который содержит nx указатели-к-междунар. Каждый из этих указателей на int просто обычный указатель, как мы видели много раз. Им еще предстоит инициализированы к чему-либо значимому, и каждый может быть доступен как либо

x[0], x[1] ... x[nx-1], OR *x, *(x+1), *(x+2),
  ... *(x+nx-1).

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

 for (i=0;i<nx;++i){
    x[i] = ( int * ) malloc( ny * sizeof(int));
  }

Обратите внимание, что мы могли бы также сказать:

for (i=0;i<nx;++i){
    *(x+i) = ( int * ) malloc( ny * sizeof(int));
  }

Теперь, когда каждый указатель в нашем массиве указателей указывает на значимый блок памяти (каждый размером ny ints) мы можем назначить ценности. Чтобы понять, как присваиваются значения, рассмотрите Схема ниже. Вам нужно будет изучить это очень тщательно, пока это очень ясно, что происходит. Это может быть немного сложно, но как только вы это освоите, все будет не так плохо.

  x[0] --->   | *x[0] | *x[0]+1 | *x[0] + 2 | ... | *x[0]+ny-1 |
  x[1] --->   | *x[1] | *x[1]+1 | *x[1] + 2 | ... | *x[1]+ny-1 |

  .
  .
  .
  x[nx-1] ---> | *x[nx-1] | *x[nx-1]+1 | *x[nx-1] + 2 | ... | *x[nx-1]+ny-1 |

Это эквивалентно:

  x[0] --->   | *(*(x+0)+0) | *(*(x+0)+1) | *(*(x+0)+2) | ... | *(*(x+0)+ny-1) |
  x[1] --->   | *(*(x+1)+0) | *(*(x+1)+1) | *(*(x+1)+2) | ... | *(*(x+1)+ny-1) |
  .
  .
  .
  x[nx-1] --->   | *(*(x+nx-1)+0) | *(*(x+nx-1)+1) | *(*(x+nx-1)+2) | ... | *(*(x+nx-1)+ny-1) |

И это эквивалентно:

  x[0] --->   | x[0][0] | x[0][1] | x[0][2] | ... | x[0][ny-1] |
  x[1] --->   | x[1][0] | x[1][1] | x[1][2] | ... | x[1][ny-1] |
  .
  .
  .
  x[nx-1] ---> | x[nx-1][0] | x[nx-1][1] | x[nx-1][2] | ... | x[nx-1][ny-1] |

... учитывая важное соотношение:

 *( *(x + i) + j) = *( x[i] + j) = x[i][j]
1 голос
/ 11 апреля 2011

Вы можете сделать это:

int ArrayName[5][5];

for(size_t i = 0; i < 5; i++)
    for(size_t i2 = 0; i2 < 5; i2++)
        ArrayName[i][i2] = 1;

Или чтобы быть более эффективным:

int ArrayName[5][5];

for(size_t i = 0, *ptr = ArrayName; i < (5*5); ++i, ++ptr)
    *ptr = 1;

Если бы вы были достаточно сумасшедшими, вы бы создали для него функцию:

void init_arr(void* ptr, void* value, size_t size)
{
    for(size_t i = 0; i < size; ++i, ++ptr)
        *ptr = *value;
}

int ArrayName[5][5];
int val = 1;
init_arr(ArrayName, val, 5 * 5);

Если вы использовали C ++, вы могли бы использовать шаблоны:

template <class T>
void init_arr(T *ptr, T value, size_t size)
{
    for(size_t i = 0; i < size; ++i, ++ptr)
        *ptr = value;
}

int ArrayName[5][5];
init_arr(ArrayName, 1, 5 * 5);

Если бы вы действительно использовали C ++, вы бы использовали векторы ... Черт, возможно, есть причудливый способ сделать это. :)

1 голос
/ 11 апреля 2011

Я не уверен, что это вообще возможно. Вы должны использовать for или while петли.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...