3

I came across a C++ program like this

#include<iostream>
using namespace std;

int main() {
    int N = 10;
    int M = 2;
    int a[] = { 2,1,4,3,6,5,8,7,10,9 };
    int(*b)[5] = (int(*)[5]) a;
    for (int i = 0; i<M; i++) {
        for (int j = 0; j<N / M; j++) {
            cout << b[i][j] << endl;
        }
    }

    system("pause");
    return 0;
}

The above program's output is 2,1,4,3,6,5,8,7,10,9. It looks like b is an array point. So what does (int(*)[5]) a mean? Can someone help me to explain it?

8
  • Explicit convert a (int[10]) to int(*)[5]. Commented Mar 29, 2017 at 8:19
  • Can you give me more detail? What is the meaning of (int(*)[5]) a? a is an array(int[10]). And int(*)[5] means a point. Can they convert directly? Commented Mar 29, 2017 at 8:24
  • @Jonas double pointer? What double pointer? Commented Mar 29, 2017 at 8:37
  • @songyuanyao Can you give me more detail? What is the meaning of (int(*)[5]) a? a is an array(int[10]). And int(*)[5] means a point. Can they convert directly? Commented Mar 29, 2017 at 8:39
  • convert it (1d array) to pointer to 2d array. Commented Mar 29, 2017 at 8:40

5 Answers 5

2

a is an int-array with 10 elements: int [10]. b is a pointer to an int-array with 5 elements: int (*) [5]. b is initialized with the value of a and explicitly casted using the C-style cast: (int(*)[5]) a.

Effectively a is a 1x10 matrix and b is a 2x5 matrix, it is in fact a "reshape" of a into b, with the same content. The "most" dangerous thing here is that the reshape does not perform a deep copy, i.e., changes to b also affect a and vice versa;

The type, here int, is completely irrelevant. Here is an online example, with several different types.

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

Comments

2

The statement

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

Looks like this in memory

     +---+---+---+---+---+---+---+---+---+---+
a -> | 2 | 1 | 4 | 3 | 6 | 5 | 8 | 7 | 10| 9 |;
     +---+---+---+---+---+---+---+---+---+---+
      +0  +1 ...  

When you access elements in the array you typically use [] but since a is an address. you can access elements also using a pointer style offset

a + 2   // address to third int, *(a+2) the actual value `3`

Now by declaring another way to access the 10 integers you can access the memory of a in a different way, the type determines the way you access the memory

int(*b)[5] = (int(*)[5]) a; // compiler, pretend a is of same type

In the above statement b and a refer to the same memory but b is of type pointer to int array of five.

since b is a pointer:

b points to where a starts. doing b++, b now points to middle of a array since declaration of b says it holds only five integers

so

b[0] points to address a + 0
b[0][0] is the value of a + 0 or a[0] alt. *(a + 0)

b[1] points to address a + 5 
b[1][0] is the value of a + 5 or a[5] alt. *(a + 5)

Since C normally has no check whether you are going out of bounds the above works.

Comments

2

Since b is a pointer to array of 5 integers so :

  • b[0] will point to an array of 5 integers stored from location pointed to by b.
  • b[1] will point to an array of 5 integers stored from location pointed to by b + (5*sizeof(int)).

Since b has been assigned address of a via typecasting int(*b)[5] = (int(*)[5]) a;, therefore:

  • b[0] will point to first 5 integers of array a i.e, a[0..4]
  • b[1] will point to next 5 integers of array a i.e, a[5..9]

Now,

  • b[0][0] will give value of 1st element indexed at 0 of array pointed to by b[0] i.e, a[0]
  • b[0][1] will give value of 2nd element indexed at 1 of array pointed to by b[0] i.e, a[1]

..

..

  • b[1][0] will give value of 1st element indexed at 0 of array pointed to by b[1] i.e, a[5]
  • b[1][1] will give value of 2nd element indexed at 1 of array pointed to by b[1] i.e, a[6]

Comments

2

Here, a[] is an array of 10 integers. b is a pointer to an array of 5 elements.

int(*b)[5] = (int(*)[5]) a;

In the above statement the address of the array a[] is type-casted to a pointer to an array of 5 elements. Then, b is accessed as a two dimensional array.

Comments

0

Int-array a is explicitly initialized to contain 10 elements. The internal representation of the variable a is a pointer to the first element. Writing a[3] is "give me the contents of a with an offset of 3".

The variable b is then created as an array of pointers (length 5) to int (it is not "point" but "pointer", btw). b is initialized with the contents of a, but since a is of a different type, it has to be typecast to the correct type (that is, b's type). Type cast basically means "pretend that the memory of variable a was of a different type". This is here done with a c-style cast

(int(*)[5]) a

All in all, I wouldn't strive to replicate this coding style.

Also, the following code only works if a pointer to int is twice the size of an int, e.g. 64 bit pointer, 32 bit int. Dirty, dirty code.

2 Comments

"The internal representation of the variable a is a pointer to the first element." - No, it isn't. Arrays are not pointers.
Ok, more precise would be to say "c-style arrays are not pointers, but you can use them as such".

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.