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 output 2,1,4,3,6,5,8,7,10,9
. Looks like the b
point of the array. So what does it mean (int(*)[5]) a
? Can someone help me explain this?
source to share
a
- is int-array with 10 elements: int [10]
. b
- a pointer to an int-array with 5 elements: int (*) [5]
. b
initialized a
and clearly exposed using C-style: (int(*)[5]) a
.
Effectively a
a 1x10 matrix, but b
a 2x5 matrix, it is actually a "change" a
in b
with the same content. The "most dangerous" thing here is that the change does not perform a deep copy; Changes to b
also affect a
and vice versa;
The type, here int
, does not matter at all. Here is an online example with several different types.
source to share
Statement
int a[] = { 2,1,4,3,6,5,8,7,10,9 };
It looks like this in memory
+---+---+---+---+---+---+---+---+---+---+
a -> | 2 | 1 | 4 | 3 | 6 | 5 | 8 | 7 | 10| 9 |;
+---+---+---+---+---+---+---+---+---+---+
+0 +1 ...
When you refer to elements in an array, you usually use [], but because it a
is an address. you can access items also use pointer style offset
a + 2 // address to third int, *(a+2) the actual value `3`
Now, by declaring another way to access 10 integers, you can access memory a
in a different way, the type determines the way to access 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
has a pointer to type int of five.
since it b
is a pointer:
b
indicates the beginning a
. doing b++
, b now points to the middle of the array a
, as b's declaration says it only contains 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 usually doesn't check if you are outside the scope of the above works.
source to share
Since it b
is a pointer to an array of 5 integers, so:
-
b[0]
will point to an array of 5 integers stored from the location it points tob
. -
b[1]
will point to an array of 5 integers stored from the location it points tob + (5*sizeof(int))
.
Since the b
address is assigned a
using typecasting int(*b)[5] = (int(*)[5]) a;
, so:
-
b[0]
will point to the first 5 integers of thea
ie array ,a[0..4]
-
b[1]
will point to the next 5 integers of thea
ie array ,a[5..9]
Now,
-
b[0][0]
will give the value of the 1st element indexed into the0
array pointed to byb[0]
ie,a[0]
-
b[0][1]
will give the value of the 2nd element indexed into the1
array pointed to byb[0]
ie,a[1]
..
..
-
b[1][0]
will give the value of the 1st element indexed into the0
array pointed to byb[1]
ie,a[5]
-
b[1][1]
will give the value of the second element indexed into the1
array pointed to byb[1]
ie,a[6]
source to share
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 [3] means "give me the content of a at offset 3".
Then the variable b is created as an array of pointers (length 5) to int (this is not a "point", but a "pointer", btw). b is initialized to the contents of a, but since a is of a different type, it must be cast to the correct type (that is, b type). The cast type basically means "to pretend the memory of the variable a is of a different type". This is done with a c-style cast
(int(*)[5]) a
In general, I would not replicate this coding style.
Also, the following code only works if the pointer to int is twice the size of an int, for example. 64-bit pointer, 32-bit int. Dirty, dirty code.
source to share