-1

I have these 3 cases from CLA certification ( C programming Language Certified associate Certification ; CPP Institute) that I would like to understand better:

  1. int *array[10]
  2. int (*array)[10]
  3. int *(*array)[10]

What are the differences between these 3 cases?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Vani
  • 7
  • 2
  • 1
    I suggest reading section 6 of the [comp.lang.c faq](http://c-faq.com/). – pmg Apr 30 '20 at 10:26
  • Does this answer your question? [Is an array name a pointer?](https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer) – dandan78 Apr 30 '20 at 11:18

2 Answers2

2

Here's what you have:

  1. An array of 10 pointers to int.
  2. A pointer to an array of 10 int.
  3. A pointer to an array of 10 pointers to int.
Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
  • Yeah sorry I read that wrong. So evidently "A pointer to an array of 10 `int*`" would be easier to read. – Lundin Apr 30 '20 at 09:58
  • @Lundin Well, I expanded it fully into English. Leaving `int *` would be an incomplete expansion. This is the standard way to describe it without the use of any parentheses or brackets or asterisks, i.e. entirely in English. – Tom Karzes Apr 30 '20 at 09:59
  • Maybe it's just me being more fluent in the C language than the English language then :) – Lundin Apr 30 '20 at 10:02
  • @Lundin Yeah, the English-language descriptions are cumbersome. I only resort to them when people want an English-language description of a declaration. – Tom Karzes Apr 30 '20 at 10:04
0

This

int *array[10]

is a declaration of an array with 10 elements of the type int *.

Here is a demonstrative program.

#include <stdio.h>

int main(void) 
{
    enum { N = 10 };
    int a[N] = 
    { 
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9 
    };

    int * array[N] = 
    { 
        &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9] 
    };

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", *array[i] );
    }
    putchar( '\n' );

    return 0;
}

Its output is

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 

This

int (*array)[10]

is a declaration of a pointer to an object having the array type int[10].

Here is another demonstrative program.

#include <stdio.h>

int main(void) 
{
    enum { N = 10 };
    int a[N] = 
    { 
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9 
    };

    int (*array)[N] = &a;

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", ( *array )[i] );
    }
    putchar( '\n' );

    return 0;
}

Its output is the same as above.

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 

This

int *(*array)[10]

is a declaration of a pointer to an object of the array type int *[10].

Here is one more demonstrative program.

#include <stdio.h>

int main(void) 
{
    enum { N = 10 };
    int a[N] = 
    { 
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9 
    };

    int * b[N] = 
    { 
        &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9] 
    };

    int *(*array)[N] = &b;

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", *( *array )[i] );
    }
    putchar( '\n' );

    return 0;
}

Again its output the same as shown above.

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 

In general if you have an array for example like this

T a[N1][N2][N3];

where T is some type specifier and N1, N2, N3 are its sizes then a pointer to such an array will look like

T ( *p )[N1][N2][N3] = &a;

Dereferencing the pointer you will get lavlue of the array itself.

For example

sizeof( *p ) is equal to the sizeof( a[N1][N2][N3] ).

Below is an example of more complicated declaration

int * ( * array[10] )[10];

It is a declaration of an array of 10 elements of pointers to arrays of 10 elements of pointer to the type int.

Here is a demonstrative program that shows how to process such an array. Investigate it.:)

#include <stdio.h>

int main(void) 
{
    enum { N = 10 };
    int a[N] = 
    { 
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9 
    };

    int * b[N] = 
    { 
        &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9] 
    };

    int * ( * array[N] )[N] = 
    { 
        &b, &b, &b, &b, &b, &b, &b, &b, &b, &b
    };

    for ( size_t i = 0; i < N; i++ )
    {
        for ( size_t j = 0; j < N; j++ )
        {
            printf( "%d ",  ( **array[i] )[j] );
        }           
        putchar( '\n' );
    }
    putchar( '\n' );

    return 0;
}

The program output is

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335