views:

207

answers:

7

This is really a noob quick question.

Imagine you have a struct called "No" and the following piece of code:

No *v_nos; // What does this mean?

Where I took this from they were calling "v_nos" a array? Isn't it simply a pointer to a struct "No"?

Thanks.

+2  A: 

Yes, it declares (but does not initialise) a pointer to a No.

Dominic Rodger
+3  A: 

You are correct, but it can also be used as an array :

v_nos = new Nos[10];
v_nos[5].whatever = something;
// etc
Samuel_xL
+2  A: 

Its a pointer to a No struct.

If they are calling it an array, that pointer could point to the first member of an array of No structs

for example

No* nos= getNosArray();//pseudocode

*nos;//first element 
*(nos+1)//2nd element;
Tom
A: 

Arrays and pointers are more or less interchangeable in C++. You can dereference an offset from a pointer - *(v_nos+2) - and it's effectively the same as indexing an array v_nos[2]. In fact you can use either notation, IIRC. Under the covers both examples tell the compiler to do the same thing: increment the pointer by 2 * the size of the pointed-at object, and then return what it finds at that location.

Avdi
They are not interchangeable. Arrays can decay into pointers, but pointer can never be converted to arrays. That is, where you do need an array you will not be able to pass a pointer: `void f( int ( f( p ); }` will not compile, even if `void f( int *p ) {} int main() { int a[3]; f(a); }` will compile by forcing the array to decay into a pointer to the first element.
David Rodríguez - dribeas
+3  A: 

In terms of implementation, arrays and pointers are the same. That is, arrays are simply implemented as pointers to the first element in the array. The difference between

No *v_nos;

and

No v_nos[3];

Is that the latter sets aside memory for 3 elements for that array, while the pointer would need to have memory allocated using malloc (or new).

You could still treat the second one as the pointer that it is though, for example *v_nos would give you the first element, &v_nos would give the address of the pointer.

Matt Moriarity
Matt Brunell
nice answer but you could replace malloc by new, the question is tagged C++ :)
Samuel_xL
This is misleading. Arrays decay (rather easily) into pointers, but they are not the same by any means. If you care to check the difference: `void f( int ( sizeof(a) /* 3 * sizeof(int) */; int *b = new int[3]; sizeof(b); /* sizeof(int*) */`
David Rodríguez - dribeas
...those two examples show ways in which arrays differ from pointers to the first element, even if when passed to a function (by value) the array will decay to a pointer to the first element.
David Rodríguez - dribeas
sellibitze
**Absolutely incorrect.** Arrays are *NOT* implemented as pointers to their first element. Array object type in most cases *"decays"* (i.e. gets converted implicitly) to pointer value when used in an expression (not in all cases though), which might create an *illusion* of array being a pointer. Yet, in reality, arrays are not pointers. They are related, but not the same.
AndreyT
A: 

typedef struct NO { int x; }_NO;

int main() { NO *v_nos; NO *v_nos_array;

v_nos = new _NO(); // allocate mem for 1 struct
v_nos_array = new _NO[100]; allocate mem for 100 structs

for(1=0; 1<100; i++) v_nos_array[i].x = i; //five some value to 'x' of each struct

for(1=0; 1<100; i++) cout << v_nos_array[i].x << "\n";

}

hope you can extract out the meaning. Note that an array with a single element is still an array.

+6  A: 

Arrays and pointers are NOT the same. In your case, the variable is a pointer, not an array. Even if they are not the same, the confusion is quite common and you will find in many places (including C/C++ books) that they are the same thing. This means that you should get acquainted to people calling pointers arrays.

When the C language was developed they decided that instead of passing arrays by value (possibly requiring a huge amount of copying and stack memory) they would convert silently the array into a pointer to the first element and then pass that pointer to the function.

void f( int a[3] ); // valid and misleading
// what it means:
// void f( int *a);
void test() {
   int array[3];
   f( array );
   // what it means:
   // f( & array[0] )
}

For backwards compatibility C++ keeps that feature around and you cannot pass arrays by value, nor define a function that takes an array by value (in both cases it will be converted to a pointer to the first element silently). At the same time, you can use the array access syntax on pointers to simplify pointer arithmetic, making it more confusing:

int array[3];
int *pointer = array; // simplified: 
// int * pointer = & array[0]
pointer[2]; // equivalent to *(pointer+2) or array[2]

This means that with regular functions both in C and C++ arrays silently decay into pointers and most people will have the idea that they are the same thing: an array is a pointer to the first element. Well, they are not.

Both in C and C++ they are different entities, even if some usage patterns are equivalent due to that design decision. But they are in fact different:

int array[3]; sizeof(array); // 3*sizeof(int)
int *p1=array;               // sizeof(int*), usually 4/8 bytes for 32/64 bit
int *p2=new int[3];          // sizeof(int*)

After passing through a function/method call, they are all pointers:

void f( int array[3] ) { sizeof(array); } // sizeof(int*) it is really a pointer! size is ignored
void g( int *p ) { sizeof(array); }       // sizeof(int*)

In C++ things become even more interesting, as pass-by-value is not the only available paradigm and you can pass by reference:

void f( int (&array)[3] ); // funny syntax to pass an array of 3 integers by reference
void testf() {
   int array1[3]; f(array1); // correct
   int array2[2]; // f(array2); compilation error, it is not an array of 3 ints!
   int *p = array1; // f(p); compilation error, it is not an array of 3 ints!
}

void g( int array[3] ); // means: void g( int *array );
void testg() {
   int array1[3]; g(array1); // correct, the array decays into & array[0]
   int array2[2]; g(array2); // correct, the array decays again
   int *p = array1; g( p );  // correct it is a pointer
}

Note that when you define a function that takes an array by value you are actually defining a function that takes a pointer by value and that the compiler will not check that the argument to the function call actually has that size. This is a known source of errors and the reason why most functions that take arrays also take a size parameter.

Lastly, you cannot create arrays dynamically, you can only acquire memory dynamically into pointers, so when you need a heap allocated array you are actually in need of a pointer into a heap allocated contiguous block o memory:

void test() {
   int *p = new int[3];
   // int array[3] = new int[3]; // error!! an array is not a pointer
   delete p;
}

At the end this all means that they are not the same thing, but that you can always use an array in the place of a pointer and it will be automatically converted by the compiler into a pointer to the first element of the array. More often than not, people will refer to pointers into a block of contiguously memory (whether stack or heap allocated) as array.

David Rodríguez - dribeas
Dear god, you are absolutely right in this statement: "...most people will have the idea that [arrays and pointers] are the same thing: an array is a pointer to the first element. Well, they are not."I've had to work through so much confusion about that statement, it's not even funny. Thanks for the clarification. And thanks to google for finding this page.
Ichimonji10