Какой самый простой способ установить значение всего массива? - PullRequest
1 голос
/ 10 июня 2010

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

int arr[4][4] = { {0,0,0,0} , {0,0,0,0} , {0,0,0,0} , {0,0,0,0} };

Но в этом случае мне нужно заполнить массив после его объявления. В настоящее время мой код отформатирован так:

int arr[4][4];
if(someothervariable == 1){
    arr = { {1,1,1,1},
            {1,2,3,4},
            {2,,3,4,5},
            {3,4,5,6} };
}

Но это не скомпилируется. Есть ли способ использовать упомянутый ярлык в моем случае? Если нет, то какое лучшее исправление доступно? Я был бы признателен за способ установить его без явного назначения каждого элемента? То есть: arr [0] [0] = ...

Ответы [ 7 ]

2 голосов
/ 10 июня 2010

Как насчет использования std :: copy ()?

int arr[4][4];
if(someothervariable == 1){
        const static int a2[4][4] = { {1,1,1,1},
                                      {1,2,3,4},
                                      {2,3,4,5},
                                      {3,4,5,6} };
        std::copy(&a2[0][0], &a2[0][0]+16, &arr[0][0]);
}
1 голос
/ 10 июня 2010

Если вы хотите заполнить массив одним значением:

#include<algorithm>
#include<vector>

// ...
std::vector<int> arr;
std::fill(arr.begin(), arr.end(), VALUE);  // VALUE is an integer

Если вы хотите рассчитать значение для каждого элемента:

struct get_value {
    int operator()() const { /* calculate and return value ... */ }
};

std::generate(arr.begin(), arr.end(), get_value());
1 голос
/ 10 июня 2010

В текущей версии языка C ++ единственный способ сделать это - скопировать его из оригинала

int arr[4][4];

if (someothervariable == 1)
{
  const int SOURCE[4][4] = // make it `static` if you prefer
  { 
    {1, 1, 1, 1},
    {1, 2, 3, 4},
    {2, 3, 4, 5},
    {3, 4, 5, 6} 
  };

  assert(sizeof arr == sizeof SOURCE); // static assert is more appropriate
  memcpy(&arr, &SOURCE, sizeof arr);
}

Исходная "константа" может быть объявлена ​​как static, чтобы избежать повторной инициализации, если компилятор не достаточно умен, чтобы оптимизировать ее сам.

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

1 голос
/ 10 июня 2010

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

Библиотека boost.assign добавляет интересный синтаксис для изменения / заполнения коллекций, но AFAIK не поддерживает массивы в стиле C (только C ++ иПовышение контейнеров).

0 голосов
/ 10 июня 2010

Я не уверен, нравится ли мне это решение или нет, но C / C ++ даст вам удобство присваивания, если вы оберните массив внутри структуры с минимальными затратами, а затем придется использовать имя структуры, чтобы получить массив :

typedef struct {
    int data[4][4];
} info_t;

info_t arr;

if (someothervariable == 1){
    static const info_t newdata = {{  // since this is static const, there generally
                                      // won't be a copy - that data will be 'baked' 
                                      // into the binary image (or at worst a
                                      // single copy will occur)
        {1,1,1,1},
        {1,2,3,4},
        {2,3,4,5},
        {3,4,5,6} 
    }};
    arr = newdata;  // easy to assign new data to the array
}

int somethingelse = arr.data[1][2]; // a tiny bit less convenient to get 
                                    //    to the array data
0 голосов
/ 10 июня 2010

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

memset (arr, 0, sizeof (arr));

Обратите внимание, что это чревато опасностями.Вы должны знать размеры шрифта и весь этот джаз.

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

Метод # 1.(Может быть боль прикладом)

arr[0][0] = 1;
...
arr[0][3] = 1;
arr[1][0] = 1;
...
arr[1][3] = 4;
arr[2][0] = 2;
...
arr[2][3] = 5;
arr[3][0] = 3;
...
arr[3][3] = 6;

Метод № 2.Предварительно определите набор массивов и переключайтесь между ними с помощью указателя;

int  arr1[4][4] = {
        {0,0,0,0},
        {0,0,0,0},
        {0,0,0,0},
        {0,0,0,0} };
int  arr2[4][4] = {
        {1,1,1,1},
        {1,2,3,4},
        {2,,3,4,5},
        {3,4,5,6} };

int *arr[4];

Теперь у вас есть только четыре (4) значения * arr [] для установки вместо установки всех параметров.Конечно, это действительно работает, только если ваши массивы будут заполнены заданными константами.

Надеюсь, это поможет.

0 голосов
/ 10 июня 2010
int arr[4][4];
if (someothervariable == 1) {
     int tmp[4][4] = { {1, 1, 1, 1}, {1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6} };
     arr = tmp;
}
...