Rain
Rain

Reputation: 3926

Converting a pointer to int into a pointer to an array of int

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

Answers (2)

Stebin
Stebin

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

dbush
dbush

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

Related Questions