ponteiro para array c ++

Qual é o código a seguir?

int g[] = {9,8}; int (*j) = g; 

Pelo que entendi, está criando um ponteiro para uma matriz de 2 ints. Mas então por que isso funciona:

 int x = j[0]; 

e isso não funciona:

 int x = (*j)[0]; 

Os parênteses são supérfluos no seu exemplo. O ponteiro não se importa se há uma matriz envolvida – só sabe que está apontando para um int

  int g[] = {9,8}; int (*j) = g; 

também poderia ser reescrito como

  int g[] = {9,8}; int *j = g; 

que também pode ser reescrito como

  int g[] = {9,8}; int *j = &g[0]; 

um ponteiro para um array seria semelhante

  int g[] = {9,8}; int (*j)[2] = &g; //Dereference 'j' and access array element zero int n = (*j)[0]; 

Há uma boa leitura nas declarações de ponteiro (e como criá-las) neste link aqui: http://www.codeproject.com/Articles/7042/How-to-interpret-complex-CC-declarations

 int g[] = {9,8}; 

Isso declara um object do tipo int [2] e inicializa seus elementos para {9,8}

 int (*j) = g; 

Isso declara um object do tipo int * e inicializa com um ponteiro para o primeiro elemento de g .

O fato de a segunda declaração inicializar j com algo diferente de g é bem estranho. C e C ++ apenas têm essas regras estranhas sobre matrizes, e essa é uma delas. Aqui a expressão g é implicitamente convertida de um lvalue referente ao object g em um rvalue do tipo int* que aponta para o primeiro elemento de g.

Essa conversão acontece em vários lugares. Na verdade, ocorre quando você faz g[0] . O operador de índice de matriz não funciona em matrizes, apenas em pointers. Então a declaração int x = j[0]; funciona porque g[0] faz a mesma conversão implícita que foi feita quando j foi inicializado.

Um ponteiro para uma matriz é declarado assim

 int (*k)[2]; 

e você está exatamente certo sobre como isso seria usado

 int x = (*k)[0]; 

(observe como “declaração segue o uso” , isto é, a syntax para declarar uma variável de um tipo imita a syntax para usar uma variável desse tipo.)

No entanto, normalmente não se usa um ponteiro para um array. Todo o propósito das regras especiais em torno de matrizes é para que você possa usar um ponteiro para um elemento de matriz como se fosse um array. Então idiomático C geralmente não se importa que matrizes e pointers não são a mesma coisa, e as regras impedem que você faça muito de qualquer coisa útil diretamente com matrizes. (por exemplo, você não pode copiar uma matriz como: int g[2] = {1,2}; int h[2]; h = g; )


Exemplos:

 void foo(int c[10]); // looks like we're taking an array by value. // Wrong, the parameter type is 'adjusted' to be int* int bar[3] = {1,2}; foo(bar); // compile error due to wrong types (int[3] vs. int[10])? // No, compiles fine but you'll probably get undefined behavior at runtime // if you want type checking, you can pass arrays by reference (or just use std::array): void foo2(int (&c)[10]); // paramater type isn't 'adjusted' foo2(bar); // compiler error, cannot convert int[3] to int (&)[10] int baz()[10]; // returning an array by value? // No, return types are prohibited from being an array. int g[2] = {1,2}; int h[2] = g; // initializing the array? No, initializing an array requires {} syntax h = g; // copying an array? No, assigning to arrays is prohibited 

Como os arrays são tão inconsistentes com os outros tipos em C e C ++, você deve evitá-los. C ++ tem std::array que é muito mais consistente e você deve usá-lo quando precisar de matrizes estaticamente dimensionadas. Se você precisa de matrizes dimensionadas dinamicamente, sua primeira opção é std :: vector.

j[0]; desreferencia um ponteiro para int , portanto, seu tipo é int .

(*j)[0] não tem tipo. *j desreferencia um ponteiro para um int , então ele retorna um int , e (*j)[0] tenta deletar um int . É como tentar int x = 8; x[0]; int x = 8; x[0]; .