-1

I have read the pointer to array c++ and have some experiment on it.

#include <iostream>
using namespace std;
int main()
{
    int g[] = {9,8};
    int (*j)[2] = &g;
    int *i = g;

    int n = (*j)[0];
    int m = *(i + 0);
    cout << "n:" << n << endl;
    cout <<"m:" << m << endl;
    cout << "=============" << endl;
    cout << "*(j):" << *(j) << endl;//9's address ???
    cout << "j:" << j << endl;//9's address ???
    cout << "&j:" << &j << endl;//what it is???
    cout << "&(*j)" << &(*j) << endl;//9's address ???
    cout << "=============" << endl;
    cout << "*(i):" << *(i) << endl;//get the value pointered by i
    cout << "i:" << i << endl;//i's value store g's address
    cout << "&i:" << &i << endl; //i's address
    cout << "&(*i):" << &(*i) << endl;//9's address
    cout << "=============" << endl;
    cout << "*(g):" << *(g) << endl;//get the value pointered by g
    cout << "g:" << g << endl;//g's value store 9's address
    cout << "&g:" << &g << endl;//9's address???
    cout << "&(*g):" << &(*g) << endl;//9's address
    return 0;
}

The result is :

n:9
m:9
=============
*(j):0x7fff56076bbc
j:0x7fff56076bbc
&j:0x7fff56076bb0
&(*j)0x7fff56076bbc
=============
*(i):9
i:0x7fff56076bbc
&i:0x7fff56076ba8
&(*i):0x7fff56076bbc
=============
*(g):9
g:0x7fff56076bbc
&g:0x7fff56076bbc
&(*g):0x7fff56076bbc
[Finished in 0.3s]

What I want to ask is:

1.Why

    int (*j)[2] = &g;
    int *i = g;

if I change either one &g to g, or g to &g, it will give a compile error, what is the difference?

(I think that the array name is a pointer, so why cannot I use int (*j)[2] = g and what is the meaning of &g, it is a pointer already, why get address again?)

2. Since the &g and g, their address are the same, why cannot be exchanged?

3. Why the &g's value is 9's address? Is it store its own address?

4. Can you explain the j variable part? I cannot understand why j stores the 9's address and *(j) gets the 9's address, &(*j) gets the 9's address too?

I am very confused about it now. What I totally understand is about the i variable part, g variable part is confused about the &g, and the j varialbe part is all confused. The int (*j)[2] = &g; part is confused too.

Community
  • 1
  • 1
Jason
  • 1,573
  • 3
  • 18
  • 46
  • 1. because their types are different (no, an array name is not a pointer), 2. because their types are different, 3. because the array's first element starts at the same location where the array itself starts, 4. see #3. –  Oct 27 '13 at 14:14
  • 1
    "I think that the array name is a pointer.." Not true. A pointer is a *variable* that holds an address. An array is a variable that *is* an address. You can modify the address *in* a pointer variable (`int *p = arr; ++p;` You *cannot* do said-same with an array. (`int arr[N]; ++arr;` is illegal and won't compile). – WhozCraig Oct 27 '13 at 14:17

3 Answers3

1
  1. g is the variable (in this case array), &g is the address of the variable (in this case the address of the beginning of the array. You might understand that, but the compiler does not, and thus it's giving you an error.

  2. They probably could be exchanged, if you were willing to do type-casting, but that's not a really good idea in this case.

  3. Because g is the array of integers, and the address of the first (0-th) element of that array just happens to be the address of the whole array. Doesn't it make sense?

  4. j in your case is a pointer to the array, of course it is also a pointer to the address with the 0-th element of that array (by definition)

v010dya
  • 5,296
  • 7
  • 28
  • 48
1

(*j)[2] is pointer to array of 2 integers. In other words it is (almost) equivalent with pointer to pointer to ints. The line int (*j)[2] = g; tries to assign int* to (int**) which is a type mismatch. The line int *i = &g; tries to assign int** to int* which is again a type mismatch.

(I think that the array name is a pointer, so why cannot I use int (*j)[2] = g and what is the meaning of &g, it is a pointer already, why get address again?)

The address of what? In its type checking C++ distinguishes address of variables of different types, so even though int* and int** are both addresses (pointers) they point to different types.

Igor Popov
  • 2,588
  • 17
  • 20
1

You can have a look at this post to understand why g and &g hold the same address:

How array name has its address as well as its first element in it?

The compiler complains when you change either of g to &g because there is a type mismatch. This means that semantically, g and &g have different meanings, even though they may refer to the same thing: g, when used in an expression, decays into pointer to int (int *), but &g is of type pointer to array of 2 ints. These are not compatible types; you can't assign a pointer to an array of ints to something that is a pointer to int (and the same happens the other way around).

Your claim that g is already a pointer is wrong: g is an array. When used in an expression, it decays into a pointer to the array's first element. A pointer is just something that holds an address; an array is an address (the address of its first element). With &g, you get a pointer to an array, you don't get pointer to pointer because arrays do not decay into pointers when the referencing operator is used. Think of it like this: if an array is an address, then applying the "address of" operator - & - yields this same address, which is, by convention, the address of the first element. When you don't apply the & operator, in an expression, the array decays into a pointer to the first element, and then again - it points to the first element, the same address as &g.

Community
  • 1
  • 1
Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70
  • Can I ask that why this different? *(g):9 g:0x7fff56076bbc *(j):0x7fff56076bbc j:0x7fff56076bbc Is j a pointer to an two integer array? – Jason Oct 27 '13 at 15:35
  • I wonder that way only *(j):0x7fff56076bbc. I think j is a pointer and its value is the address of the array. Then *j will decay to pointer to *(j+0), but I don't know why it isn't the value 9. – Jason Oct 27 '13 at 15:45
  • In C, declarations follow use; this means that when you write something like `int (*j)[2]`, `(*j)[i]` is of type `int`. Similarly, `(*j)` (or `*(j)`) is of type "array of 2 ints". When used in an expression, an array represents the address of the first element; since `*j` is an array, then `*j` holds the address of the first element, namely, the address of `(*j)[0]`. However, an array **is** an address, so `j` also holds that same address, because that's what you assigned it to. – Filipe Gonçalves Oct 27 '13 at 16:05