Reputation: 3926
I'm reading a book about the C language and it says
The assignment of an array name to a pointer to an array of ints, such as
a
, is implicitly converted into a pointer to the array’s first element, not a pointer to the whole array and it requires an explicit type conversion.
So the following code would give "Error: mismatched pointer types".
int(*arrPtr)[4] = NULL;
int a[4] = {7, 8, 9, 5};
arrPtr = a;
We should change it to
arrPtr = (int(*)[4])a;
My question is why it's required to do type casting when we can simply get the address of the whole array a
using &
operator.
arrPtr = &a;
Is there any advantage in doing the cast? aren't they both the same?
Upvotes: 1
Views: 126
Reputation: 24
To clarify, here a is a pointer of type int* and points to the 0th element of the array. arrPtr is a pointer that can point to an array of 4 integers. So arrPtr and a are two different pointer types. And the compiler throws a warning if you try to assign a to arrPtr. But you can still do this assignment in C however it is not the way to do it. Note that arrPtr = a & arrPtr = &a assigns the same memory address to arrPtr. But for &a the compiler doesn't show any warning.
See the below progarm output to get more clarity on this,
int main()
{
int(*arrPtr)[4] = NULL;
int(*arrPtrtemp)[4] = NULL;
int *ptr;
int a[4] = {7, 8, 9, 5};
arrPtr = a;
arrPtrtemp = &a;
ptr = a;
printf("arrPtr:%p\n", arrPtr);
printf("arrPtrtemp:%p\n", arrPtrtemp);
printf("ptr:%p\n", ptr);
arrPtr++;
arrPtrtemp++;
ptr++;
printf("arrPtr:%p\n", arrPtr);
printf("arrPtrtemp:%p\n", arrPtrtemp);
printf("ptr:%p\n", ptr);
return 0;
}
Will give the following output:
arrPtr:0x7ffc1bf19820
arrPtrtemp:0x7ffc1bf19820
ptr:0x7ffc1bf19820
arrPtr:0x7ffc1bf19830
arrPtrtemp:0x7ffc1bf19830
ptr:0x7ffc1bf19824
Note that arrPtr & arrPtrtemp are same and works same irrespective of the compiler warning. The purpose of this typecasting arrPtr = (int(*)[4])a; is to convet int* to int(*)[4]. The main difference between int & int()[4]** comes in pointer arithmetic. so if we assume the size of an integer is 4 bytes in our system, an operation like ptr++(an int* pointer) will increment the address by 4 bytes. And arrPtr++ (an int(*)[4] pointer) will increment the address by 16 bytes.
Edit:- here a is a pointer of type int* and points to the 0th element of the array. Change to the following,
When using the array name a to assign the address of the 0th element of the array, the compiler checks the pointer type of a as int*. And by using & operator to get the address of array a, the compiler will treat the pointer type of &a as int (*)[4] in this case. And no warning will be displayed.
Upvotes: 0
Reputation: 223699
An explicit cast is needed here:
arrPtr = (int(*)[4])a;
Because the pointer types are not compatible. However, that doesn't mean that such a conversion is valid. Taking the address as you stated:
arrPtr = &a;
Would be the correct thing to do, and elements of a
can then be access via arrPtr
with notation such as (*arrPtr)[n]
.
Upvotes: 1