Absolutelyrun
Absolutelyrun

Reputation: 51

what is the difference between *pt in int (*pt)[2] and pt in int *pt?

For example

    int (*pt)[4];
    int target[3][4] = {{1,3,4,6},{2,4,5,8},{3,4,6,7}};
    pt = target;
    *pt = target[0];

why it is "[Error] invalid array assignment"

Upvotes: 1

Views: 513

Answers (3)

H.S.
H.S.

Reputation: 12669

OP has asked two question.

Question 1

what is the difference between *pt in int (*pt)[2] and pt in int *pt?

In this

int (*pt)[4];

the pt is a pointer which can point to an array of 4 integers.

Assume array of 4 integer - int arr[4] = {1,3,4,6};

You can do

pt = &arr;  //pt is now pointing to array arr.

In context of your program

pt = target;

this is equivalent to

pt = &target[0];

because target is address of first element of array which is a 1D array:

target  ->  target + 0  ->  &(*(target + 0)  ->  &target[0]

and target[0] is array of 4 integers.

Note that type of *pt is int [4] and when you use *pt in your program you will get address of first element of array it is pointing to and which is also the base address of array:

*pt  ->  *pt + 0  ->  &(*(*pt + 0))  ->  &(*pt)[0]

Consider this

#include <stdio.h>

int main (void)
{
    int (*pt)[4];
    int target[3][4] = {{1,3,4,6},{2,4,5,8},{3,4,6,7}};
    pt = target;  // pointer pt pointing to target[0] array
    printf ("%p\n", (void *)*pt);
    printf ("%p\n", (void *)&target[0][0]);
    return 0;
}

Output:

# ./a.out
0x7ffee35389e0
0x7ffee35389e0

Coming to 2nd part of question, in this statement

int *pt;

Here, pt is pointer to an integer.

Assume you have array of 4 integer - int arr[4] = {1,3,4,6};

When you do

pt = arr;

is equivalent to

pt = *arr[0];

because

arr  ->  arr + 0  ->  &(*(arr + 0))  ->  &arr[0]

So, *pt will give the value at the address it is pointing to.

Consider this example:

#include <stdio.h>

int main (void)
{
    int *pt;
    int arr[4] = {1,3,4,6};
    pt = arr;
    printf ("%p\n", (void *)pt);
    printf ("%p\n", (void *)arr);
    printf ("%p\n", (void *)&arr[0]);
    printf ("%d\n", *pt);
    return 0;
}

Output:

# ./a.out
0x7ffee86f0a00
0x7ffee86f0a00
0x7ffee86f0a00
1

Question 2

why it is "[Error] invalid array assignment"

*pt = target[0];

Note that the pt is pointer to array of 4 integer. The type of *pt - int [4]. An array name is not a modifiable lvalue and you cannot assign to it. Hence, compiler is giving error on this statement.

Upvotes: 1

David C. Rankin
David C. Rankin

Reputation: 84551

Adding slightly to the excellent answer given by Barmar,

int (*pt)[4];

declares a pointer to array of int [4]

int target[3][4] = {{1,3,4,6},{2,4,5,8},{3,4,6,7}};

declares an array of arrays int [4] (3 of them in a common 2D array)

pt = target;

on access target is converted to a pointer to its first element. (array / pointer conversion) Since its first element is an array of int [4] it is converted to a pointer to array of int [4] which is type-compatible with pt. See C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)

*pt = target[0];

Since pt is a pointer to array of int [4], when you dereference the pointer you are left with an array of int [4] -- and arrays are not lvalues and not assignable. Id at (p1).

Upvotes: 2

Barmar
Barmar

Reputation: 780909

int (*pt)[4] declares pt as a pointer to an array.

C doesn't allow assigning arrays; e.g. you can't do:

int a[4] = {1, 2, 3, 4};
int b[4];
b = a;

If you want to copy an array, you need to use a loop, or you can use memcpy:

memcpy(pt, target[0], sizeof target[0]);

Upvotes: 3

Related Questions