2012-05-25 16 views
11
#include <stdio.h> 

int main() 
{ 
    printf("%d", sizeof(struct token *)); 
} 

Il codice di cui sopra può essere compilato e collegato uso gcc sotto Linux. Qualcuno di voi potrebbe spiegarmi la cosa dietro le Scene? So che il punto prende la dimensione fissa della memoria, quindi il token struct è irrilevante per sizeof, ma attiva anche l'opzione di avviso in gcc, nessun avviso sulla struttura "none exists". Il contesto per la domanda è che sto leggendo qualche codice sorgente da altri, sto cercando molto duramente di trovare la definizione di "struct token", ma ovviamente fallita.perché è possibile utilizzare struct definito in c

+6

Non è necessario 'struct gettone 'Da definire (e nemmeno dichiarato) per ottenere la dimensione di un puntatore ad esso. –

risposta

12

Poiché si sta tentando di ottenere le dimensioni di un puntatore a struct token. La dimensione di un puntatore non dipende da come viene effettivamente definita la struttura.

In genere, è possibile dichiarare una variabile di tipo struct token*, ma non è possibile dereferenziarlo (ad esempio, accedere a un membro tramite il puntatore).

+0

In C++, è possibile dichiarare 'struct token *', ma non è possibile dichiarare 'token *'. Non capisco perché il secondo non è permesso. – Deqing

+0

Perché solo "token" non è un tipo incompleto, mentre "struct token" è, quindi il compilatore non può riconoscere "token" come un tipo. Pensala solo come una limitazione sintattica. –

9

Per parafrasare lo standard C, un tipo incompleto è un tipo che descrive un oggetto ma non dispone delle informazioni necessarie per determinarne le dimensioni.

vuoto è un altro tipo incompleto. A differenza di altri tipi incompleti, void non può completare .

Questo "tipo incompleto" viene spesso utilizzato per i tipi di handle: una libreria consente di assegnare un "handle" a qualcosa, lavorare con esso e smaltirlo nuovamente. Tutto questo accade incapsulato nella libreria. Tu come utente non hai idea di cosa potrebbe accadere all'interno.

Esempio:

lib.h:

struct data * d_generate(void); 
void d_set(struct data *, int); 
int d_get(struct data *); 
void d_free(struct data*); 

lib.c:

#include "lib.h" 
#include <stdlib.h> 
struct data { int value; }; 
struct data * d_generate(void) { 
    return malloc(sizeof(struct data)) 
} 
void d_set(struct data * d, int v) { 
    d -> value = v; 
} 
int d_get(struct data * d) { 
    return d->value; 
} 
void d_free(struct data* d) { 
    free(d); 
} 

user.c:

#include "lib.h" 
[...] 
struct data * d = d_generate(); 
d_set(d, 42); 
int v = d_get(d); 
// but v = d->value; doesn't work here because of the incomplete definition. 
d_free(d); 
+1

Questo è comunemente noto come [tipo opaco] (http://en.wikipedia.org/wiki/Opaque_pointer#C) in C e può essere utilizzato per ottenere meccanismi orientati agli oggetti come l'incapsulamento e il polimorfismo. – Lundin

Problemi correlati