Почему эта запись массива недопустима в C? - PullRequest
1 голос
/ 10 декабря 2011

Если это возможно:

#include <stdio.h>
#include <process.h>

#define SIZE 5

void PassingArray(int arr[])
{
    int i=0;
    for(i=0 ; i<SIZE ; i++)
    {
        printf("%d, ", arr[i]);
    }
    printf("\n");
}

main()
{
    int myIntArray[5] = {1, 2, 3, 4, 5};

    PassingArray(myIntArray);

    system("PAUSE");
}

Тогда почему следующее незаконно?

#include <stdio.h>
#include <process.h>

#define SIZE 5

int ReturningArray()[]
{
    int myIntArray[5] = {1, 2, 3, 4, 5};

    return myIntArray;
}

main()
{
    int myArray[] = ReturningArray();

    system("PAUSE");
}

Ответы [ 5 ]

4 голосов
/ 10 декабря 2011

Вы не возвращаете int, но вы возвращаете массив.Это то же значение, что и &myIntArray[0].int ReturningArray()[] не является допустимым прототипом функции.

2 голосов
/ 10 декабря 2011

Есть несколько причин, почему это не работает.

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

Во-вторых, даже если бы было разрешено объявлять ReturningArray, как вы это делаете, вы никогда не могли бы написать в этой функции действительный оператор return - выражение с типом массива, который не является субъект унарных операторов & или sizeof вычисляет указатель на первый элемент массива, который больше не имеет тип массива. Так что вы не можете return увидеть массив.

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

2 голосов
/ 10 декабря 2011

PassingArray допустимо, но не передает массив. Он передает указатель на первый элемент массива. void PassingArray(int arr[]) является запутанным синонимом для void PassingArray(int *arr). Вы не можете передать массив по значению в C.

ReturningArray недопустимо, вы не можете вернуть массив по значению в Си. Обычный обходной путь - вернуть структуру, содержащую массив:

typedef struct ReturnArray {
    int contents[5];
} ReturnArray;

ReturnArray ReturningArray()
{
    ReturnArray x = {{1, 2, 3, 4, 5}};
    return x;
}

Массивы являются гражданами второго сорта в C, тот факт, что они не могут быть переданы или возвращены по значению, исторически связан с тем фактом, что они не могут быть скопированы по присваиванию. И, насколько я знаю, причина этого кроется в ранней разработке C, задолго до того, как он был стандартизирован, когда еще не было решено, как будут работать массивы.

2 голосов
/ 10 декабря 2011

Есть несколько проблем с этим кодом.

  1. Вы ставите скобки не в том месте. Вместо

    int ReturningArray()[]
    

    должно быть

    int* ReturningArray()
    
  2. Вы возвращаете локальную переменную. Локальные переменные существуют только во время выполнения функции и впоследствии будут удалены.

Чтобы сделать это, вам нужно будет malloc массив int и вернуть указатель на массив:

#include <stdio.h>
#include <malloc.h>

#define SIZE 5

int* ReturningArray()
{
    int *myIntArray = (int *)malloc(SIZE * sizeof(int));
    myIntArray[0] = 1;
    myIntArray[1] = 2;
    myIntArray[2] = 3;
    myIntArray[3] = 4;
    myIntArray[4] = 5;
    return myIntArray;
}

int main(void)
{
        int i;
        int* myArray = ReturningArray();
        for(i=0;i<SIZE;i++) { 
                printf("%d\n", myArray[i]); 
        }
        free(myArray); // free the memory again
        system("PAUSE");
        return 0;
}
0 голосов
/ 10 декабря 2011

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

int myIntArray[] = {1, 2, 3, 4, 5};

int (*ReturningArray())[sizeof(myIntArray)/sizeof(int)] {

    return &myIntArray;
}
...