Mảng được truyền dưới dạng con trỏ tới các phần tử.
Nếu tôi viết:
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]);
}
đầu ra sẽ là "0 5 2". Đó là bởi vì C truyền bất cứ điều gì thực sự là tham số theo giá trị. Tham số là một con trỏ tới một int. Vì vậy, một con trỏ đến một int được truyền theo giá trị. Do đó, doStuff nhận được một bản sao của một con trỏ tới bộ nhớ trong khung stack chính. Khi nó dereferences con trỏ với ptr[1]
, nó là sau con trỏ đến bộ nhớ chính và sửa đổi các mảng đó.
C chỉ có thể truyền theo giá trị, nhưng nó có thể "cạn". Nếu bạn yêu cầu nó vượt qua một int *, nó sẽ truyền một int *. Nó chỉ sao chép giá trị của con trỏ, chứ không phải giá trị của bất kỳ giá trị nào trỏ tới.
Nếu bạn muốn doStuff để có được bản sao riêng của mảng, hoặc quấn mảng trong một cấu trúc như những người khác đã gợi ý, hoặc sử dụng memcpy tự sâu sao chép các mảng như thế này:
void doStuff(int *ptr, int nElems)
{
int myCopyOfTheArray[nElems];
memcpy(myCopyOfTheArray, ptr, sizeof(int) * nElems);
/* do stuff with the local copy */
}
Không giống như sử dụng một cấu trúc, cách tiếp cận memcpy hoạt động nếu nElems chỉ biết trong thời gian chạy.
Tôi tin câu trả lời (chi tiết) của tôi cho câu hỏi khác này http://stackoverflow.com/questions/3613302/passing-array-of-struc tures-to-function-c/3613350 # 3613350 cũng đề cập đến điều này. Về cơ bản đó là sự khác biệt giữa vấn đề mảng và con trỏ. – kriss
Bạn không thể sử dụng const, nếu bạn không muốn sửa đổi nội dung mảng? – Nyan