What is a pointer to array, int (*ptr)[10], and how does it work?
Asked Answered
A

5

8
int (*ptr)[10];

I was expecting ptr to be an array of pointers of 10 integers.

I'm not understanding how it is a pointer to an array of 10 integers.

Adey answered 26/9, 2020 at 11:1 Comment(7)
It is a pointer to an array of 10 elements. Whereas this int *ptr[10] is the array of 10 pointers.Abcoulomb
The Clockwise/Spiral RuleMoffatt
C or C++ ? Please pick oneNominate
cdecl.orgZealand
As you're new to the site, let me remind you that you can choose to accept one of these answers, more details in What should I do when someone answers my question?.Hierolatry
Does this answer your question? meaning of these pointers, pointer-to-pointer, function pointer and array pointerKoval
No one really does all these figuring out things. You just get used to the common ones like array pointers, array references, function pointers etc, and when you find something particularly messy, you use tools like cdecl.org.Koval
T
5

I like to read it like this: (great answers already posted)

int (*ptr) [10];
     ^ a pointer
           ^ to an array of 10
^ ints

vs

int* ptr[10];
        ^ array of 10
   ^ pointer to int
Tuff answered 26/9, 2020 at 11:13 Comment(1)
Yours is not so bad either :)Hierolatry
R
4

ptr is of type "pointer to array of 10 int". In your declaration it is uninitialized so it doesn't point to any object. To make it point to an array:

int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

// initialize in the declaration:
int (*ptr) [10] = &arr;

// or after:
int (*ptr) [10];
ptr = &arr;
Reyesreykjavik answered 26/9, 2020 at 11:4 Comment(1)
Not my downvote. The only inaccuracy I see is that the pointer is default initialized (with an indeterminate value), rather than being uninitialized.Koval
H
3

A pointer to an array of 10 ints is meant to point to arrays of 10 elements, no more, no less, or in case you have a 2D array, to point to a given row of such array, provided the it has exactly 10 columns.

An array of pointers to int, int *ptr[10], is just that, it has 10 pointers to int and to each one you can assing an address of an int, it can be part of an array or not.

Example 1:

int (*ptr)[10];

int arr[10];
ptr = &arr; //correct, arr has 10 elements

int arr2[12]; 
ptr = &arr2; //not correct, arr2 does not have 10 elements

Such pointer can be used to point to a 2D array with undetermined number of rows but a fixed number of columns.

Example 2:

int arr[5][10];
ptr = arr; //correct, pointer to the 1st row of a 2D array with 10 cols
ptr++; //now points to the second row        
    
int arr2[5][12]; 
ptr = arr2; //not correct, incompatible pointer, has too many cols

Example 3:

int(*ptr)[3];

int arr[2][3] = {{1, 2, 3}, {4, 5, 7}};
ptr = arr;

printf("%d", ptr[1][2]); //array indexing is identical as using arr[1][2] 

Array of pointer vs pointer to array

An advantage of pointer to array comes when it's time to dynamically allocate/free memory:

Example with a 2D array with 4 rows and 5 columns:

int (*ptr)[5]; 
ptr = calloc(5, sizeof *ptr); //simple assignment

free(ptr); //simple deallocation
int *ptr[5];

for (int i = 0; i < 5; i++)  //each pointer needs it's own allocation
    ptr[i] = calloc(5, sizeof **ptr);

for (int i = 0; i < 5; i++)  //each pointer needs to be freed
    free(ptr[i]);

On the other hand if you have an array of pointers you can have an uneven array, that is to say that the 1st row can have 10 ints but the 2nd can have 20:

int *ptr[5];

for (int i = 0; i < 5; i++)
    ptr[i] = calloc( i + 1, sizeof **ptr);

In the above example the 1st row of the 2D array has space for 1 int, the second for 2, the third for 3 and so on.

Hierolatry answered 26/9, 2020 at 11:4 Comment(0)
B
3

A declaration gives a “picture” of how a variable will be used.1 int (*ptr) [10] says “When (*ptr)[i] is used in an expression, it is an int.” From this, we can derive the type of ptr:

  • Since (*ptr)[i] is an int, (*ptr) must be an array of int.
  • Since (*ptr) is an array of int, *ptr must be an array of int.
  • Since *ptr is an array of int, ptr must be a pointer to an array of int.

Footnote

1 Kernighan and Ritchie, The C Programming Language, 1978, page 90.

Belindabelisarius answered 26/9, 2020 at 11:59 Comment(0)
A
1

In both expressions and declarations, the postfix operators [] and () have higher precedence than unary *. Because of this, the declarations

T *a[N]; // a is an array of pointer to T
T *f();  // f is a function returning pointer to T

are parsed as

T *(a[N]); // result of a[i] will be dereferenced
T *(f());  // result of f() will be dereferenced

If you want a pointer to an array or a pointer to a function, you must explicitly group the * operator with whatever the pointer expression will be:

T (*a)[N]; // result of *a will be subscripted
T (*f)();  // result of *f will be executed

The pointer does not have to be a simple identifier - you can have a function that returns a pointer to an array:

T (*f())[N]; // result of *f() will be subscripted

or an array of pointers to functions

T (*a[N])(); // result of *a[i] will be executed
Argillaceous answered 26/9, 2020 at 12:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.