这是由于数组往往会衰变为指针的事实引起的。
int a[] = { 1, 2, 3 };
int* p = a; // valid: p is now the address of a[0]
a = p; // NOT valid.
printf("a = %p\n", a);
printf("p = %p\n", p); // prints same address as a
a
和p
将打印相同的值。
与其他人所说的相反,a
不是指针,而只是可以衰变成一个指针。http://c-faq.com/aryptr/aryptrequiv.html
在您的第一个function()
中,传递的是数组第一个元素的地址,并且函数体对其进行了解引用。实际上,编译器将函数原型视为:
void function(int* array ){
array[0] = 4;
array[1] = 5;
array[2] = 6;
}
function(&array[0]);
这是必须发生的,因为你说了“大小未知的数组”(int array[])。编译器无法保证通过值传递所需的堆栈量,因此将其衰减为指针。
---- 编辑 ----
让我们结合你们两个的例子,并使用更明显的名称使事情更加清晰。
#include <stdio.h>
void func1(int dynArray[]) {
printf("func1: dynArray = %p, &dynArray[0] = %p, dynArray[0] = %d\n",
dynArray, &dynArray[0], dynArray[0]);
}
void func2(int* intPtr) {
printf("func2: intPtr = %p, &intPtr[0] = %p, intPtr[0] = %d\n",
intPtr, &intPtr[0], intPtr[0]);
}
void func3(int intVal) {
printf("func3: intVal = %d, &intValue = %p\n",
intVal, &intVal);
}
int main() {
int mainArray[3] = { 1, 2, 3 };
int mainInt = 10;
printf("mainArray = %p, &mainArray[0] = %p, mainArray[0] = %d\n",
mainArray, &mainArray, mainArray[0]);
func1(mainArray);
func2(mainArray);
printf("mainInt = %d, &mainInt = %p\n",
mainInt, &mainInt);
func3(mainInt);
return 0;
}
在ideone上有实时演示:http://ideone.com/P8C1f4
mainArray = 0xbf806ad4, &mainArray[0] = 0xbf806ad4, mainArray[0] = 1
func1: dynArray = 0xbf806ad4, &dynArray[0] = 0xbf806ad4, dynArray[0] = 1
func2: intPtr = 0xbf806ad4, &intPtr[0] = 0xbf806ad4, intPtr[0] = 1
mainInt = 10, &mainInt = 0xbf806acc
func3: intVal = 10, &intValue = 0xbf806ad0
在
func1
和
func2
中,"dynArray"和"intPtr"是局部变量,但它们是指针变量,从主函数中接收"mainArray"的地址。
这种行为仅适用于数组。如果您将数组放在结构体中,则可以按值传递它。