array=constant pointer?

Hello!
Please, is an array ALWAYS (by default) a constnat pointer, even if not particualrly written const?

Many thanks!

An array is not a pointer.

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main()
{
    char array[64] ;
    const char* pointer = array ;

    std::cout << "sizeof(array)   = " << sizeof(array) << '\n' ;
    std::cout << "sizeof(pointer) = " << sizeof(pointer) << '\n' ;
}
sizeof(array)   = 64
sizeof(pointer) = 4


http://ideone.com/cf7slF
Hello!
Excuse me, I ment NAME of the pointer.

1
2
3
4
5
6
7
8
9
10
...

int ar[2]={2,6};
int* p=ar;
ar++;  // error???
arr+=2 //error???

return 0;
}


Many thanks!
Please, is an array ALWAYS (by default) a constnat pointer, even if not particualrly written const?


the array name is a constant pointer to the first element of the array, and a constant cannot be change

1
2
3
4
5
6
7
8
9
10
11
12
int ar[ 2 ] { ... }

ar++; // error !! ar is constant, it cannot be changed
ar+=2; // same error

int* p = ar;
// is the same as :
int* p = &ar[ 0 ];
// or
int* p = &ar;

p++ // okay! this will point to the 2nd element in ar 
Last edited on
shadow fiend wrote:
yes, the array name is a constant pointer to the first element of the array, and a constant cannot be change.


An array name is an identifier. It is not a pointer, constant or otherwise, as illustrated in the code I posted above. It may be convenient to think of it as a constant pointer in some contexts as the behavior is mostly the same, and it is implicitly convertible to a pointer, but it is not, itself, a pointer.

shadow fiend wrote:
1
2
3
4
5
6
7
8
9
10
11
12
int ar[ 2 ] { ... }

ar++; // error !! ar is constant, it cannot be changed
ar+=2; // same error

int* p = ar;
// is the same as :
int* p = &ar[ 0 ];
// or
int* p = &ar;

p++ // okay! this will point to the 2nd element in ar     


You might want to revisit some of your assumptions: http://ideone.com/ihml4r
This is one of those things that is hard to understand in C and C++ just because people have to be so pedantic about this stuff. (With good reason.)

From what you are trying to understand, then yes, it is a const pointer.

Except that an array is not a pointer, which is the point cire is making.


When compiling, the compiler understands int a[12] to have a named value called 'a' which consists of the following information:
- address of the first element in the array (a const pointer!)
- type of elements in the array
- length of the array

In contrast, a pointer int* p only has the following information associated with it:
- address of the element it addresses (a pointer)
- type of the element it addresses

These two things are pretty darn close. In code generated to access stuff, it is exactly the same:

    a[2]    is semantically equivalent to    *(p + 2)


What muddles it is that an array address is a pointer, so using an array's name (its identifier) in a pointer context causes it to degenerate into a pointer. This happens when passing to a function, for example:

1
2
3
4
5
6
7
8
9
10
11
12
void print( int* p )
  {
  cout << *p << endl;
  }

int main()
  {
  int a[ 5 ] = { 2, 3, 5, 7, 11 };

  print( a );
  print( a + 3 );
  }
2
7

It is the same reason that you must pass the length of an array to a function:

1
2
3
4
5
6
7
8
9
10
11
12
13
void print( int* p, unsigned size )
  {
  for (unsigned n = 0; n < size; n++)
    cout << p[ n ] << " ";
  cout << "\b\n";
  }

int main()
  {
  int a[ 5 ] = { 2, 3, 5, 7, 11 };

  print( a, 5 );  
  }
2 3 5 7 11

You can make life easier with a template function helper:

1
2
3
4
5
6
7
8
9
10
11
12
13
template <unsigned N>
inline
void print( int (&a)[ N ] )
  {
  print( a, N );
  }

int main()
  {
  int a[ 5 ] = { 2, 3, 5, 7, 11 };

  print( a );  
  }
2 3 5 7 11

The reason the helper works, of course, is that 'a' is an array, which knows its size. So when you call print( a ), the function helper gets called instead of any pointer function.

If you want to use them together, though, you have to help the compiler, since the array will degenerate into a pointer at the earliest convenience. So make sure you use references for everything to force the compiler to choose the correct item.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using namespace std;

void print( int*& p )
  {
  cout << *p << endl;
  }

void print( int* p, unsigned size )
  {
  for (unsigned n = 0; n < size; n++)
    cout << p[ n ] << " ";
  cout << "\b\n";
  }

template <size_t N>
inline
void print( int (&a)[ N ] )
  {
  print( a, N );
  }

int main()
  {
  int a[ 5 ] = { 2, 3, 5, 7, 11 };

  print( a );
                  
  int* p = a;
  
  print( p );
  }
2 3 5 7 11
2

It's enough to make your head swim, no?
(YES!:D)Thanks!!!
Last edited on
Topic archived. No new replies allowed.