Question:
In C++ you can do the following:
int variavel[10][10];
int** variavel;
But what about when I want to create a 2d array, where I can have the first part "unlimited" and the second part with a limit?
tipo ponteiro nova_variavel[limite]
And the "inverse"?
tipo nova_variavel[limite] ponteiro
For example:
int* a[5]; //Ponteiro de arrays
Or
std::vector<int*> a; //Array de ponteiros
char* A[6];
A[1] = "Hello,";
A[2] = " World";
std::array<char*,2> a;
a[1] = "Hello,";
a[2] = "World!"; // <- Repare 1 caractere a mais. É pouco, mas pode fazer diferença.
Answer:
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 this array is lista
. When you write lista[4][2]
you access an element and that results in an int
. However if you just write lista
in your expression, that is, when you try to access the array by name, it will decay into 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 then do the following:
int lista[10][10];
int* ponteiro1 = lista; // ponteiro1 é &lista[0][0]
int* ponteiro2 = lista[3]; // ponteiro2 é &lista[3][0]
Now when you do the following
int** ponteiro;
It's just creating a pointer that points to a pointer that points to an int
. There are no arrays here. The ponteiro[2][3]
notation that is possible represents 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 an int*
pointer.
The last notation of your question ( tipo nova_variavel[limite] ponteiro
) would have the objective of creating a pointer named nova_variavel
that points to an array of limite
elements of type tipo
? In this case its 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 avoid 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