"x" 和 C 中的“&x[0]”有什么区别吗?
Is there any difference between "x" and "&x[0]" in C?
浏览一些用 C 编写的软件,我遇到了以下代码,我可以总结如下:
void fill_array_with_some_data(int *_)
{
// assign some arbitrary int values to _[0] and _[1]
_[0] = 42;
_[1] = 24;
}
int main(int argc, char **argv)
{
int x[2] = {0};
fill_array_with_some_data(&x[0]);
// do something with the data which is now is x
if (x[0] & 0x42)
// do something
return 0;
}
看到 &x[0]
而不是 x
对我来说似乎很奇怪。
两者有区别吗?
有什么理由可以使用 &x[0]
而不是简单地 x
吗?
除了风格之外没有任何区别。
将 &x[0]
作为参数传递可能表明程序员只希望函数访问第一个元素,而传递 x
则意味着他们希望函数访问整个数组。但这仅仅是约定俗成的,问题中给出的代码示例显然甚至不遵守这一约定。
就语言标准而言,这些表达式是完全等价的,至少在计算上下文中(sizeof
除外):&x[0]
是 shorthand for &*(x + 0)
,可以简化为&*x
,然后是x
。
在fill_array_with_some_data(&x[0])
中,x
和&x[0]
是等价的。
在int x[2] = {0];
之后,x
指定一个数组。当在表达式中使用数组时,它将转换为指向其第一个元素的指针,除非:
- 作为sizeof的操作数,如
sizeof x
,
- 它被用作一元
&
的操作数,如&x
,或
- 它是一个用于初始化数组的字符串文字,如
char s[] = "abc";
。
因此 sizeof x
将给出数组的大小,而 sizeof &x[0]
将给出指向 x
.
元素的指针的大小
&x
和 &x[0]
都指向内存中的相同位置,但它们具有不同的类型。 x
的类型是“指向 2 int
的数组的指针”,&x[0]
的类型是“指向 int
的指针”。这意味着 &x + 1
将指向整个数组末尾 x
之后,但 &x[0] + 1
将指向元素 x[0]
之后(因此它指向 x[1]
).
一般情况下,只有在想要具体指向元素时才写&x[0]
。当用一些数据填充数组时,程序员应该写 fill_array_with_some_data(x)
来表达他们希望例程对整个数组进行操作。这对编译器没有影响,但它有助于人们理解正在做什么。人们应该只使用 &x[0]
来特别指出该元素。例如,如果一个例程 foo
只对一个元素进行操作,我们可以写 foo(&x[0])
来向 reader.
表明这一点
浏览一些用 C 编写的软件,我遇到了以下代码,我可以总结如下:
void fill_array_with_some_data(int *_)
{
// assign some arbitrary int values to _[0] and _[1]
_[0] = 42;
_[1] = 24;
}
int main(int argc, char **argv)
{
int x[2] = {0};
fill_array_with_some_data(&x[0]);
// do something with the data which is now is x
if (x[0] & 0x42)
// do something
return 0;
}
看到 &x[0]
而不是 x
对我来说似乎很奇怪。
两者有区别吗?
有什么理由可以使用 &x[0]
而不是简单地 x
吗?
除了风格之外没有任何区别。
将 &x[0]
作为参数传递可能表明程序员只希望函数访问第一个元素,而传递 x
则意味着他们希望函数访问整个数组。但这仅仅是约定俗成的,问题中给出的代码示例显然甚至不遵守这一约定。
就语言标准而言,这些表达式是完全等价的,至少在计算上下文中(sizeof
除外):&x[0]
是 shorthand for &*(x + 0)
,可以简化为&*x
,然后是x
。
在fill_array_with_some_data(&x[0])
中,x
和&x[0]
是等价的。
在int x[2] = {0];
之后,x
指定一个数组。当在表达式中使用数组时,它将转换为指向其第一个元素的指针,除非:
- 作为sizeof的操作数,如
sizeof x
, - 它被用作一元
&
的操作数,如&x
,或 - 它是一个用于初始化数组的字符串文字,如
char s[] = "abc";
。
因此 sizeof x
将给出数组的大小,而 sizeof &x[0]
将给出指向 x
.
&x
和 &x[0]
都指向内存中的相同位置,但它们具有不同的类型。 x
的类型是“指向 2 int
的数组的指针”,&x[0]
的类型是“指向 int
的指针”。这意味着 &x + 1
将指向整个数组末尾 x
之后,但 &x[0] + 1
将指向元素 x[0]
之后(因此它指向 x[1]
).
一般情况下,只有在想要具体指向元素时才写&x[0]
。当用一些数据填充数组时,程序员应该写 fill_array_with_some_data(x)
来表达他们希望例程对整个数组进行操作。这对编译器没有影响,但它有助于人们理解正在做什么。人们应该只使用 &x[0]
来特别指出该元素。例如,如果一个例程 foo
只对一个元素进行操作,我们可以写 foo(&x[0])
来向 reader.