I'm reading C Primer and it really confused me when I read this:
int odd[] = {1, 3, 5, 7, 9};
int even[] = {0, 2, 4, 6, 8};
//return a pointer, which points an array with 5 int
decltype(odd) *arrPtr(int i)
{
return (i % 2) ? &odd : &even;
}
int main()
{
cout << "odd: " << odd << endl;
cout << "even: " << even << endl;
cout << arrPtr(3);
}
The result is:
odd: 0x472010
even: 0x472030
0x472010
What puzzles me is why there is a need for &. I mean, is it necessary to add a '&'?
I tried to delete & like this:
return (i % 2) ? odd : even;
And it just doesn't work:
[Error] cannot convert 'int*' to 'int (*)[5]' in return
Here's what I thought:
It can't be 'address of odd', for it will become a second-order pointer. So it must be a reference.(This is my opinion)
So the question is, why must it be a reference?
Can anyone explain this for me? Any answer is welcomed. Thanks a lot.
CodePudding user response:
decltype(odd) *arrPtr(int i)
This line is saying that you are going to return a pointer to an int
array of size 5.
When you do
return (i % 2) ? odd : even;
You are trying to return an int
array of size 5, not a pointer to it. Thus, the &
in
return (i % 2) ? &odd : &even;
Is then taking the address of odd
or even
, and returning that as a pointer, which is what the function expects you to return.
Note: in C , you cannot return an array, but you can return pointers.
Also note: The type, when using &
is int (*)[5]
, not int **
, and the return type of the function is essentially int (*)[5]
, not int *
Also also note: As noted in the comments below, typically speaking, if you want to return just an integer array, you can use the return type of int *
. An int[5]
will be implicitly cast to a int *
upon return. The use of the decltype(odd)
is adding complexity.
CodePudding user response:
Why '&' here means reference?
It doesn't mean reference here. It is the addressof operator.
What puzzles me is why there is a need for &. I mean, is it necessary to add a '&'?
Because we are returning a pointer to the array. You get a pointer to the array using the addressof operator.
It can't be 'address of odd'
It can be, and it is.
for it will become a second-order pointer.
No. Pointer to array is not a second order pointer. Furthermore, second order pointers would be allowed, so this reasoning doesn't work.
So it must be a reference.
& means a reference only as a part of a type name (or function qualifier). It never means a reference as part of an expression.
I think I get part of it, but if I get the address of the pointer, it turns out 'int**'
You don't get the address of a pointer, so nothing "turns out int**
".
You get the address of an array, so you get a pointer to the array.
how is it possible to assign it to 'int*'?
You don't assign to int*
. You return the pointer to the array and insert it into an output stream.
CodePudding user response:
This decalres an array:
int odd[] = {1, 3, 5, 7, 9};
The type of the array is int [5]
. Arrays can decay to a pointer to their first element, that is &odd[0]
. And thats what is happening when you write: return (i % 2) ? odd : even;
. The type of the pointer to first element is int*
. The function, however, returns decltype(odd) *
, a pointer to an array of 5
integers, that is int (*) [5]
. And you can get a pointer to the array via the address-of operator: &odd
.
Arrays are not pointers. Arrays can decay to pointers to their first element. This pointer is not the same as pointer to the whole array. &odd
and &odd[0]
point to the same memory location, but they are of different type. The first is a int (*) [5]
, pointer to array of 5
integers, the latter is int*
, pointer to int
.