lbs0912
lbs0912

Reputation: 331

C++ array pointer

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?

Upvotes: 3

Views: 294

Answers (5)

nyemul
nyemul

Reputation: 71

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.

Upvotes: 2

sameerkn
sameerkn

Reputation: 2259

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]

Upvotes: 2

AndersK
AndersK

Reputation: 36082

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.

Upvotes: 2

Jonas
Jonas

Reputation: 7017

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.

Upvotes: 2

Daniel
Daniel

Reputation: 1447

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.

Upvotes: 0

Related Questions