数组类型 - 规则的函数参数分配/使用 [英] Array Type - Rules for assignment/use as function parameter
问题描述
当我需要一个数组传递给一个函数,似乎所有的功能下面的声明将工作
when I need to pass an array to a function, it seems all the following declarations of the function will work
void f(int arr[])
void f(int arr[4]) // is this one correct?
本:
int a[]={1,2,3,4};
f(a);
但是,当我将数组分配到另一个阵列,它失败
But when I assign an array to another array, it fails
int a[]={1,2,3,4};
int b[4] = a; // error: array must be initialized with a brace-enclosed initializer
那么,为什么作为函数的参数传递一个数组是好的,但在简单的赋值的RHS使用的是错误的?
So why an array passed as an argument of a function is okay, but used on the rhs of simple assignment is wrong?
推荐答案
有关理解的差异,我们需要了解两种不同的上下文的
For understanding the difference, we need to understand two different contexts.
- 在值的上下文中,类型的数组的名称
T
相当于一个指针键入T
,并等于一个指针数组的第一个元素。 - 在对象的背景下,键入
T
数组的名称不减少的指针。
- In value contexts, the name of an array of type
T
is equivalent to a pointer to typeT
, and is equal to a pointer to the array's first element. - In object contexts, the name of an array of type
T
does not reduce to a pointer.
什么是对象上下文?
在 A = B;
, A
为对象范围内。当你采取一个变量的地址,它在对象上下文的使用。最后,当你使用的sizeof
运营商的一个变量,它的对象上下文中使用。在所有其他情况下,一个变量在数值上下文中使用。
In a = b;
, a
is in object context. When you taken the address of a variable, it's used in object context. Finally, when you use sizeof
operator on a variable, it's used in object context. In all other cases, a variable is used in value context.
现在,我们有这方面的知识,当我们这样做:
Now that we have this knowledge, when we do:
void f(int arr[4]);
是究竟的等同于
void f(int *arr);
当你发现了,我们可以省略函数声明的大小(4以上)。这意味着你可以不知道传递给 F中的数组的大小()
。后来,当你这样做:
int a[]={1,2,3,4};
f(a);
在函数调用,名称 A
是价值的背景下,所以它减少了一个指向 INT
。这是一件好事,因为˚F
期望一个指向 INT
,因此函数定义和使用相匹配。什么是传递给 F()
是指向 A
(&放的第一要素; A [0]
)
In the function call, the name a
is in value context, so it reduces to a pointer to int
. This is good, because f
expects a pointer to an int
, so the function definition and use match. What is passed to f()
is the pointer to the first element of a
(&a[0]
).
在的情况下
int a[]={1,2,3,4};
int b[4] = a;
名称 B
是在对象上下文中使用,并且不降低到指针。 (顺便说一句, A
这里的是一个值上下文的,并减少了一个指针。)
The name b
is used in a object context, and does not reduce to a pointer. (Incidentally, a
here is in a value context, and reduces to a pointer.)
现在, INT B〔4〕;
指定的4 INT
S吸价值,并给出了名称 b
它。 A
也被分配了类似的存储。所以,实际上,上述转让是指,我要让存储位置相同,previous位置。这是没有意义的。
Now, int b[4];
assigns storage worth of 4 int
s and gives the name b
to it. a
was also assigned similar storage. So, in effect, the above assignment means, "I want to make the storage location the same as the previous location". This doesn't make sense.
如果你想的复制的内容 A
到 B
,那么你可以这样做:
If you want to copy the contents of a
into b
, then you could do:
#include <string.h>
int b[4];
memcpy(b, a, sizeof b);
或者,如果你想要一个指针 B
是指向 A
:
int *b = a;
在这里, A
是价值的背景下,并减少了一个指向 INT
,所以我们可以指定 A
到为int *
。
Here, a
is in value context, and reduces to a pointer to int
, so we can assign a
to an int *
.
最后的初始化数组时的,可以分配给它明确值:
Finally, when initializing an array, you can assign to it explicit values:
int a[] = {1, 2, 3, 4};
下面,一个有4个元素,初始化为1,2,3和4也可以这样做:
Here, a has 4 elements, initialized to 1, 2, 3, and 4. You could also do:
int a[4] = {1, 2, 3, 4};
如果有在列表比数组中元素的数目较少的元素,则这些值的其余部分被取为0:
If there are fewer elements in the list than the number of elements in the array, then the rest of the values are taken to be 0:
int a[4] = {1, 2};
设定 A [2]
和 A [3]
0
这篇关于数组类型 - 规则的函数参数分配/使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!