Массив передается как указатель на элементы.
Если я напишу:
void doStuff(int *ptr)
{
ptr[1] = 5;
}
int main()
{
int arr[] = {0, 1, 2};
doStuff(arr);
printf("%d %d %d\n", arr[0], arr[1], arr[2]);
}
вывод будет "0 5 2". Это потому, что C передает то, что на самом деле является параметром, по значению. Параметр является указателем на int. Таким образом, указатель на int передается по значению. Таким образом, doStuff получает копию указателя на память в кадре стека main. Когда он разыменовывает этот указатель с помощью ptr[1]
, он следует за указателем на основную память и изменяет там массив.
C может проходить только по значению, но это происходит "мелко". Если вы попросите его передать int *, он передаст int *. Он только копирует значение указателя, а не значения всего, на что он указывает.
Если вы хотите, чтобы doStuff получал свою собственную копию массива, либо оберните массив в структуру, как предлагали другие, либо используйте memcpy для глубокого копирования массива вручную следующим образом:
void doStuff(int *ptr, int nElems)
{
int myCopyOfTheArray[nElems];
memcpy(myCopyOfTheArray, ptr, sizeof(int) * nElems);
/* do stuff with the local copy */
}
В отличие от использования структуры, подход memcpy работает, если nElems известен только во время выполнения.