3 回答
TA贡献1860条经验 获得超8个赞
为了理解差异,我们需要了解两种不同的情况。
在值上下文中,type数组的名称T等效于type 的指针T,并且等于指向数组第一个元素的指针。
在对象上下文中,类型数组的名称T不简化为指针。
什么是对象上下文?
在中a = b;,a是在对象上下文中。当您获取变量的地址时,将在对象上下文中使用它。最后,当sizeof在变量上使用运算符时,将在对象上下文中使用它。在所有其他情况下,在值上下文中使用变量。
现在我们有了这些知识,当我们这样做时:
void f(int arr[4]);
它正好相当于
void f(int *arr);
如您所知,我们可以从函数声明中忽略大小(上面为4)。这意味着您无法知道传递给的“数组”的大小f()。稍后,当您这样做时:
int a[]={1,2,3,4};
f(a);
在函数调用中,名称a位于值上下文中,因此将其简化为的指针int。这很好,因为f需要指向的指针int,所以函数定义并使用match。传递给的f()是指向a(&a[0])第一个元素的指针。
如果是
int a[]={1,2,3,4};
int b[4] = a;
该名称b在对象上下文中使用,并且不会简化为指针。(顺便说一下,a这里是在值上下文中,并简化为指针。)
现在,int b[4];分配4 ints的存储时间并为其命名b。 a还被分配了类似的存储空间。因此,实际上,上述分配表示“我要使存储位置与先前的位置相同”。这没有道理。
如果要将内容复制a到中b,则可以执行以下操作:
#include <string.h>
int b[4];
memcpy(b, a, sizeof b);
或者,如果你想要一个指针b是指向a:
int *b = a;
在这里,它a是在value上下文中,并简化为的指针int,因此我们可以分配a给int *。
最后,在初始化数组时,您可以为其分配显式值:
int a[] = {1, 2, 3, 4};
在这里,a有4个元素,分别初始化为1、2、3和4。您也可以这样做:
int a[4] = {1, 2, 3, 4};
如果列表中的元素数少于数组中的元素数,则其余值将取为0:
int a[4] = {1, 2};
将a[2]和设置a[3]为0。
TA贡献1852条经验 获得超7个赞
void f(int arr[]);
void f(int arr[4]);
语法具有误导性。它们都与此相同:
void f(int *arr);
即,您正在传递一个指向数组开头的指针。您不复制阵列。
- 3 回答
- 0 关注
- 388 浏览
添加回答
举报