2012-04-27 18 views
18

Ci scusiamo per il titolo scadente, ma non so come descrivere meglio questo problema.Operatori di asterisco e staffa C++ utilizzati insieme

Qual è il significato di:

int (*x)[]; 

e come inizializzarlo?

So che non è int *x[] dal:

int a,b; 
int (*x)[] = {&a, &b}; 

non verrà compilato.

Grazie in anticipo.

risposta

25

dichiarazioni tipo hanno una sintassi di espressione simile, in modo da poterli analizzare come si farebbe con l'espressione:

 x  x is 
    *x  a pointer 
    (*x)[] to an array of unknown dimensions 
int (*x)[] of int 

La regola di precedenza è che gli operatori di bind destra più stretto di quelli a sinistra, in ogni caso, l'operatore più vicino all'elemento lega stretto, e, infine, che le parentesi possono essere utilizzati per modificare queste binding, quindi:

int *x[]; is an array of pointers, 
int *(x[]); as is this. 
int (*x)[]; whereas here, the parentheses change the bindings. 
+1

+1 .... Fantastico! – Nawaz

13

Utilizzando cdecl, si può facilmente determinare il tipo:

declare x as pointer to array of int

Quindi è possibile inizializzare x con l'indirizzo di un array:

int a[]; // conceptual: error if compiled 
x = &a; 

Nota che la dimensione della matrice è parte di il suo tipo, quindi non è possibile assegnare l'indirizzo di una matrice di dimensioni N a un puntatore all'array di dimensioni M, dove N!=M (questo è il motivo dell'errore sopra riportato: è necessario conoscere la dimensione dell'array dichiararla)

int b[5]; 
int c[6]; 
int (*y)[6]; 
y = &b; // error 
y = &c; // OK 
+0

Uptick per menzionare 'cdecl' - Avevo dimenticato che esistesse - anche se rigorosamente, supporta solo la sintassi C. –

+0

Grazie per il collegamento, è utile! – Chlind

3

int (*x)[] utilizzando un puntatore a un array int vuoto. Ma inizializzare una matrice vuota non è possibile in C++. Solo tu puoi definirlo. Si dovrebbe usare una matrice non vuota:

int a[2] = {1, 2}; 
int (*x)[2] = &a; 
+1

GCC lamenta che non può convertire 'int (*) [2]' in 'int (*) []'. Edit: Ora devia dalla domanda;) – chris

+0

hai ragione, l'ho corretto. –

2

int (*x)[] significa x è un puntatore a int array. Si può fare in questo modo:

int a[] = {1, 2}; 
int (* b)[2] = &a; 

Quando interpretato variabile array tipizzato, dovremmo andare da destra a sinistra. per esempio.

int *x[] 

indica che x è un array, elementi dell'array è tipizzata come int * cioè puntatore a int. Quindi x rappresenta una matrice i cui elementi sono puntatore int. Tuttavia, le parentesi cambiano la precedenza dell'operatore. Ora * viene interpretato per la prima volta indicando che x è un puntatore, il cui tipo è int []. Pertanto, x in int (*x)[] è un puntatore all'array int e dovresti inizializzarlo di conseguenza.

+0

Non compilato: errore: impossibile convertire 'int (*) [2]' in 'int (*) []' nell'assegnazione – Attila

+0

@Attila Qual è il tuo compilatore, funziona correttamente su 'gcc 4.1.2'. :) –

+0

http : // Ideone.com/- Penso che usi gcc nella parte posteriore, ma non so quale versione/opzioni – Attila

1

I era solito avere problemi con la scrittura di C, fino a quando ho appreso come è stato creato.

In C, il tipo è descritto nel modo in cui si utilizzerà una variabile di quel tipo.

Pertanto, quando si vede:

int *x; 

significa che l'espressione *x è di tipo int, così x è variabile di tipo puntatore a int.

e se si vede:

int x[5]; 

significa che l'espressione x[3] è di tipo int, così x è una variabile di tipo array-di-int.

Quindi, per raggiungere la vostra espressione:

int (*x)[]; 

significa che l'espressione *x è di tipo int[] (vale a dire, una serie di int di dimensione sconosciuta). Pertanto x è una variabile di tipo pointer-to-an-array-of-int.

+1

Sei sostanzialmente corretto ma potresti essere ancora più chiaro. Quando vedi 'int * x' significa che' * x' è * una variabile * di tipo int. Nel modo in cui lo hai detto, non è chiaro se intendevi che '* x' era un * valore * di tipo int o una * variabile * di tipo int. –

+0

@EricLippert: '* x' non è una variabile, è un'espressione. Ho introdotto "espressione" e "variabile" dappertutto per contrassegnare la distinzione e, si spera, rendere le cose più chiare. –

+2

Ovviamente '* x' è una * variabile *; rappresenta una * posizione di memorizzazione * che * è possibile assegnare valori a *, quindi è una * variabile *; questo è ciò che una variabile * è *: una posizione di memoria a cui è possibile assegnare valori. I programmatori C, naturalmente, tendono a chiamare cose come "lvalues" piuttosto che "variabili" che è sfortunata; "lvalue" è un modo confuso e inutilmente jargonesco di dire "variabile". –

0

int (* x) [] Questo significa x è un puntatore a un array int inizializzazione come: int (* x) []; int a [10]; x = & a;

int * x [] Ciò significa x è un array di puntatori a int int * x [10]; int a [10]; x [0] = a;

A mio parere, utilizzare sempre variabili di array inizializzate o utilizzare int ** x invece di * x [] e quindi allocare memoria su runtime.

+0

Il primo esempio di utilizzo non viene compilato: errore: impossibile convertire 'int() [10]' in 'int() []' nell'assegnazione – Attila

Problemi correlati