Arrays and pointers are quite different concepts. A pointer has nothing to do with an "unlimited array". Come on:
int lista[10][10];
Here you are declaring a two-dimensional array with 100 elements. The name of that array is lista
. When you write lista[4][2]
you access an element and this results in a int
. However if you write only lista
in its expression, that is, when you try to access the array by name, it decay on a pointer to the first element. The detail here is that it is not possible to represent the array type directly, it will decay into a pointer whenever requested. You can do the following then:
int lista[10][10];
int* ponteiro1 = lista; // ponteiro1 é &lista[0][0]
int* ponteiro2 = lista[3]; // ponteiro2 é &lista[3][0]
When you do the following
int** ponteiro;
It’s just creating a pointer that points to a pointer that points to a int
. There are no arrays here. The notation ponteiro[2][3]
that it is possible to represent a bit of algebra with pointers, being equivalent to *(*(ponteiro+2)+3)
. This may not even result in a valid memory location.
Yet another possibility:
int* lista2[10]; // array de ponteiros
Here you have a simple one-dimensional list, whose element is a pointer int*
.
The last notation of your question (tipo nova_variavel[limite] ponteiro
) would aim to create a name pointer nova_variavel
pointing to an array of limite
elements of the type tipo
? In this case your definition is written like this:
int (*variavel)[10]; // ponteiro de arrays
Not so intuitive, perhaps. An example:
int main() {
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int (*ponteiro_para_array)[10] = &array;
cout << (*ponteiro_para_array)[5] << endl; // mostra 6
}
One way to escape these complications when declaring a variable with an unusual type is to name each part of its type. For example (C++11):
using int10 = int[10]; // Cria um alias para a array de 10 ints
int10* variavel; // Exatamente o mesmo que a declaração anterior
The question is already answered, but if I may add that although it is easier to use, multi-dimensional arrays are much less efficient than one-dimensional arrays, either by the number of allocations, is because the memory stays in different places and harms the cache. You will always be able to use an array[100] instead of an array[10][10].
– C. E. Gesser
@C.E.Gesser actually, it’s best to use an STL container :). But IF I needed to, I would use two-dimensional arrays to make it more organized (depending on the case, of course!).
– user2692
@C.E.Gesser the allocation of a multidimensional is also linear in memory. And say
array[a][b]
is as efficient as it would bearray[a*10+b]
. There’s not that much difference.– Guilherme Bernal
@Lucashenrique A container will cause dynamic and potentially non-linear allocation (except
std::array
). So they are not ideal in all cases. But yes, they are the easiest and least likely alternative to errors.– Guilherme Bernal
For an array is true, I was referring more to cases where something like
int **array = new int*[N]; for(int i=0; i<N; ++i) array[i] = new int[M];
, I should have been more explicit. About the containers,std::vector
always has a contiguous allocation. It is almost never wrong to choose it.– C. E. Gesser
@C.E.Gesser STL Forever!
– user2692