Going through some piece of software written in C, I encountered the following bit of code, which I can summarize as such:
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;
}
Seeing &x[0]
instead of simply x
seemed odd to me.
Is there any difference between both?
Is there any reason why one would want to use &x[0]
rather than simply x
?
CodePudding user response:
There aren’t any differences other than style.
Passing &x[0]
as an argument may suggest that the programmer only wants the function to access the first element, where passing x
would imply they expect the function to access the whole array. But that would be merely conventional, and the code sample given in the question clearly does not even respect this convention.
As far as the language standard is concerned, the expressions are exactly equivalent, at least in evaluated contexts (other than sizeof
): &x[0]
is a shorthand for &*(x 0)
, which can be simplified to &*x
and then x
.
CodePudding user response:
In fill_array_with_some_data(&x[0])
, x
and &x[0]
are equivalent.
After int x[2] = {0];
, x
designates an array. When an array is used in an expression, it is converted to a pointer to its first element except when:
- it is used as the operand of sizeof, as in
sizeof x
, - it is used as the operand of unary
&
, as in&x
, or - it is a string literal used to initialize an array, as in
char s[] = "abc";
.
Thus sizeof x
will give the size of the array, whereas sizeof &x[0]
will give the size of a pointer to an element of x
.
&x
and &x[0]
will both point to the same location in memory, but they have different types. x
has type “pointer to array of 2 int
, and &x[0]
has type “pointer to int
”. This means &x 1
will point to after the end of the entire array x
, but &x[0] 1
will point to after the element x[0]
(so it points to x[1]
).
Generally, one would write &x[0]
only when one wants to point specifically to the element. When filling the array with some data, programmers should write fill_array_with_some_data(x)
to convey they expect the routine to operate on the entire array. This makes no difference to the compiler, but it helps humans understand what is being done. One should use &x[0]
only to call out that element particularly. For example, if a routine foo
operates on only one element, we might write foo(&x[0])
to indicate that to the reader.