Инициализировать массив, используя указатель на существующий массив - PullRequest
0 голосов
/ 12 июня 2018

Я уже понял, что нельзя присвоить массивы массивам в c.Оператор типа:

int array1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int array2[10];
int * array3 = array;

Действителен, но последовательный оператор:

array2 = array1;

Нет, так как массивы затухают в указатели.Я нахожу это неудовлетворительным, так как в случае, если у меня есть функция, которая создает массив:

int * arrcreate()  {
   static int funcarray[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
   return funcarray
}

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

int main() {
   int array[10];
   int i;
   int * p = arrcreate();
   for(i = 0; i<10, i++) {
      array[i] = p[i];
   }
}

Но так как я ЗНАЮ, что при инициализации массива можно выполнять присваивание вида:

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

Я хотел бы спросить, можно ли также назначить массив с указателем на массив.

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

Ответы [ 3 ]

0 голосов
/ 12 июня 2018

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

void copy_array(const int *a, const int arraySize, int **b) {
    *b = malloc(arraySize * sizeof(*a));
    for (int indx = 0; indx < arraySize; indx++) {
        (*b)[indx] = a[indx]; 
    }
}

int main() {
    int array1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int *array2;
    copy_array(array1, &array2);
    // do stuff
    free(array2);
}

Это опция?

0 голосов
/ 12 июня 2018

К сожалению, ответа нет.В проекте n1570 для C11 говорится в 6.7.9 Инициализация:

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

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

Это означает, что массив int может быть инициализирован только заключенным в скобки списком целочисленных значений.И указатель на массив не следует этому определению.

0 голосов
/ 12 июня 2018

Неформально говоря, массив не может быть lvalue.Это означает, что массив не может находиться слева от присваивания.

Во-вторых, обратите внимание, что int array1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; не присвоение, но инициализация массива .

Если вы небрежно относитесь к терминологии, оба предложения кажутся противоречивыми.Но они не;кроме того, вы можете видеть, что не можно инициализировать массив, используя значения, на которые указывает конкретный указатель.Вам нужно что-то использовать в строках memcpy.

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