传递 &arr(整个块的地址)或仅传递数组名称(第一个元素的地址)有什么区别吗?
Is there any difference in passing &arr(address of entire block) or just passing name of array (address of first element)?
void func1(int* ptr)
{
printf("func1 :%d\n",++ptr);
}
int main()
{
int arr[4] = {0,1,2,3};
printf("Addr enter code here`f arr: %d\n",arr);
func1(arr); // first way:
func1(&arr); // second way: How this will be different from func1(arr).
}
数组衰减为指针。这些指针中的任何一个都引用内存中的相同地址。区别在于这个指针的类型。
int arr[5];
arr
和 &arr[0]
的类型为 指向 int 的指针 (int *
)
&arr
的类型为 指向五个元素整数数组的指针 ( int (*)[5]
)
我们有一个名为 func1
的函数,它接受一个 指向 int
的指针,也就是说,它的参数是 int*
。现在让我们看看每种情况下发生了什么。
案例一
在这种情况下我们有 func1(arr);
这里的变量 arr
是一个 数组,大小为 4,元素类型为 int
(即 int [4]
),但它 [由于类型衰减,=61=]衰减到第一个元素(即int*
)的指针.
所以当你写的时候,
func1(arr);
本质上,您将 int*
作为 参数 传递, 匹配 与函数类型 参数.
案例二
在这种情况下我们有 func1(&arr);
此处&arr
表示指向大小为4且元素类型为int
的数组的指针。(即int (*)[4]
)。
现在当你写的时候,
func1(&arr);
本质上,您将 int (*)[4]
作为 参数 传递给函数 func1
。但是注意func1
的参数是int*
类型的。所以在参数类型和参数中存在不匹配。
现在在您发布的屏幕截图中,程序似乎正在编译和执行成功。但请注意,由于在第二种情况下,参数和参数类型中存在 不匹配,您将得到 未定义的行为。
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has undefined behavior.
1有关未定义行为的更准确的技术定义,请参阅 this 其中提到:没有对程序行为的限制.
&arr
和arr
的区别在于前者的类型是指向数组的指针int (*)[4]
,后者的类型是数组int[4]
它可以衰减到指向第一个元素 int*
的指针。指向数组的指针和指向第一个元素的衰减指针都指向同一个地址,因为数组的第一个字节也是数组第一个元素的第一个字节。
func1(&arr)
和 func1(arr)
的区别在于前者格式错误,因为 int (*)[4]
不会隐式转换为 int*
。为了能够调用 func1(&arr)
,您必须接受正确类型的指针:
void func1(int (*ptr)[4])
printf("func1 :%d\n",++ptr);
printf("Addr enter code here`f arr: %d\n",arr);
这两个调用都会导致未定义的行为。可变参数的类型必须与格式说明符所需的类型相匹配。您使用了格式说明符 %d
,它要求参数的类型为 int
(或类似)。这里的(衰减的)参数的类型是 int*
而不是 int
.
void func1(int* ptr)
{
printf("func1 :%d\n",++ptr);
}
int main()
{
int arr[4] = {0,1,2,3};
printf("Addr enter code here`f arr: %d\n",arr);
func1(arr); // first way:
func1(&arr); // second way: How this will be different from func1(arr).
}
数组衰减为指针。这些指针中的任何一个都引用内存中的相同地址。区别在于这个指针的类型。
int arr[5];
arr
和&arr[0]
的类型为 指向 int 的指针 (int *
)&arr
的类型为 指向五个元素整数数组的指针 (int (*)[5]
)
我们有一个名为 func1
的函数,它接受一个 指向 int
的指针,也就是说,它的参数是 int*
。现在让我们看看每种情况下发生了什么。
案例一
在这种情况下我们有 func1(arr);
这里的变量 arr
是一个 数组,大小为 4,元素类型为 int
(即 int [4]
),但它 [由于类型衰减,=61=]衰减到第一个元素(即int*
)的指针.
所以当你写的时候,
func1(arr);
本质上,您将 int*
作为 参数 传递, 匹配 与函数类型 参数.
案例二
在这种情况下我们有 func1(&arr);
此处&arr
表示指向大小为4且元素类型为int
的数组的指针。(即int (*)[4]
)。
现在当你写的时候,
func1(&arr);
本质上,您将 int (*)[4]
作为 参数 传递给函数 func1
。但是注意func1
的参数是int*
类型的。所以在参数类型和参数中存在不匹配。
现在在您发布的屏幕截图中,程序似乎正在编译和执行成功。但请注意,由于在第二种情况下,参数和参数类型中存在 不匹配,您将得到 未定义的行为。
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has undefined behavior.
1有关未定义行为的更准确的技术定义,请参阅 this 其中提到:没有对程序行为的限制.
&arr
和arr
的区别在于前者的类型是指向数组的指针int (*)[4]
,后者的类型是数组int[4]
它可以衰减到指向第一个元素 int*
的指针。指向数组的指针和指向第一个元素的衰减指针都指向同一个地址,因为数组的第一个字节也是数组第一个元素的第一个字节。
func1(&arr)
和 func1(arr)
的区别在于前者格式错误,因为 int (*)[4]
不会隐式转换为 int*
。为了能够调用 func1(&arr)
,您必须接受正确类型的指针:
void func1(int (*ptr)[4])
printf("func1 :%d\n",++ptr); printf("Addr enter code here`f arr: %d\n",arr);
这两个调用都会导致未定义的行为。可变参数的类型必须与格式说明符所需的类型相匹配。您使用了格式说明符 %d
,它要求参数的类型为 int
(或类似)。这里的(衰减的)参数的类型是 int*
而不是 int
.