6

How can you interpret the following line of code?

int (*arrayABC)[10];

In my textbook, it says that we have a pointer to a pointer to the 0th element of an integer array.

However, I don't quite understand this.

My interpretation: We have some variable, which gets as its value some address. This address is then the address of the 0th element of an UNNAMED integer array. Basically we have a pointer to the 0th element.

Why then to have a pointer TO A POINTER?

4
  • Admittedly it wouldn't have been enough to answer your question, but when you are having trouble with a C declaration, Cdecl is always a good starting point. What textbook is it, anyway? Commented Jan 4, 2017 at 22:00
  • Note that it is sometimes good and useful to have a pointer to a pointer. As the answers explain, however, that's not what you have in your example. Commented Jan 4, 2017 at 22:03
  • @FabioTurati The link can be tailored. Example arrayABC as pointer to array 10 of int Commented Jan 4, 2017 at 22:20
  • 1
    Could you perhaps leave a note about which book you are reading and post the exact quote? So we can blacklist the book and shame the author publicly on the internet. Commented Jan 5, 2017 at 7:53

4 Answers 4

18

This is a pointer to an array. It is not a pointer to a pointer. Arrays and pointers are different. An array has an address, but an array is not an address. An array is a series of contiguous elements.

This pointer points to the whole array and not just the first element, in the same way that a float * points to the whole float and not just the first byte.

If you have for example:

int foo[10];
int (*arrayABC)[10] = &foo;

then the expressions (*arrayABC) and foo are identical. E.g. foo[3] is the same as (*arrayABC)[3].

Sign up to request clarification or add additional context in comments.

12 Comments

So basically this expression is the same as int arrayABC[10] with the exception that we can do something like arrayABC++?
@KevinWu no it is not much like that. The difference between int x[10]; and int (*x)[10]; is the same as the difference between float y; and float *y;
What happens then if I dereference? (Do *arrayABC)
@KevinWu added that to my answer. You can use (*arrayABC) in exactly the same way and with the same behaviour as you would use the name of the array that it points to.
@raymai97 yes, write int b[10]; memcpy(b, *arrayABC, sizeof b); . The assignment operator does not work with arrays in C, you have to use memcpy or a loop assigning element by element.
|
4

If you have an object of a type T then a pointer to the object is declared like

T obj;

T *ptr = &obj;

Now let's the type T is defined the following way

typedef int T[10];

Thus the code above

T obj;

T *ptr = &obj;

can be rewritten using the typedef definition like

int obj[10];

int (*ptr)[10] = &obj;

In the both cases, when T is some abstract type and when T is an alias for int[10], ptr is a pointer to an object. In the last case ptr is a pointer to an array of 10 elements of type int. That is the object pointed to by ptr has array type. Arrays and poiters are different types.

Try the following simple demonstrative program

#include <stdio.h>

int main( void )
{
    typedef int T[10];

    T a;

    T *pa = &a;

    printf( "%zu\n", sizeof( *pa ) );

    int b[10];

    int ( *pb )[10] = &b;

    printf( "%zu\n", sizeof( *pb ) );
}    

Its output is

40
40

As you can see the both values are equal to the size of an integer array of 10 elements. So the pointers point to arrays.

If you write

int *arrayABC[10];

you will get an array of 10 pointers of type int *.

If you write

int (*arrayABC)[10];

you will get a pointer to an array of 10 integers.

Comments

3

In my textbook, it says that we have a pointer to a pointer to the 0th element of an integer array.

Your textbook is ... badly worded, let's leave it at that. It's a pointer to a 10-element array of int.

I can kind of see where the book is coming from. Given the declaration

int (*a)[10];

the expression *a will have type int [10] (10-element array of int). However, unless that expression is the operand of the sizeof or unary & operators, it will be converted ("decay") from type int [10] to int *, and the value of the expression will be the address of the first element of the array:

Expression       Type        "Decays" to        Value
----------       ----        -----------        -----
        *a       int [10]    int *              Address of first element of the array;
                                                equivalent to `&(*a)[0]`.  

Thus, if I call a function like

foo( *a );

what the function actually receives will be a pointer to the first element of the pointed-to array (its type will be int *, not int **).

So in effect, yes, a often winds up behaving as a pointer to a pointer to the first element of the array; however, its type is not "pointer to pointer to int", and type matters. Given:

int (*a)[10];
int **b;

then you'll get different behavior for the following:

sizeof *a vs. sizeof *b
a + i vs b + i (also applies to a++ vs b++)

Comments

1

First, decide is it array or not:
[] have higher "priority"

int *A[7];    // [] then * 
int (*A)[7];  // *  then []

So, if you want a single pointer, make it a high "priority" with ()

int *(*A[4])[7];

[4] of * to 
            [7] of * to
                        int
int *(*(*A)[4])[7]; // single pointer to
int *(*    [4])[7]; // array of pointers to
int *          [7]; // array of pointers to
int               ; // PROFIT!!!

1 Comment

I'm not sure that this adds anything to this old Q&A; if you are trying to explain the clockwise/spiral rule, that could be more clear.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.