2010-02-20 19 views
109

Si può assegnare un'istanza di una struttura ad un altro, in questo modo:assegnare una struct ad un altro in C

struct Test t1; 
struct Test t2; 
t2 = t1; 

ho visto il lavoro per strutture semplici, bu funziona per strutture complesse?
Come fa il compilatore a sapere come copiare gli elementi dati in base al loro tipo, ad esempio distinguendo tra uno int e una stringa?

risposta

107

Sì se la struttura è dello stesso tipo. Pensalo come una copia di memoria.

+56

Ricorda che non c'è una copia profonda, indica che la memoria non viene copiata. –

+2

Anche qui la concorrenza è un problema. –

+12

@Tim La concorrenza non è più un problema di quanto lo sia per l'assegnazione dei tipi incorporati, come numeri interi e doppi - l'assegnazione non è un'operazione atomica per questi. –

108

Sì, l'assegnazione è supportata per le strutture. Tuttavia, ci sono problemi:

struct S { 
    char * p; 
}; 

struct S s1, s2; 
s1.p = malloc(100); 
s2 = s1; 

Ora i puntatori di entrambe le strutture puntano alla stessa blocco di memoria - il compilatore non copia la punta ai dati. Ora è difficile sapere quale istanza della struct possiede i dati. Questo è il motivo per cui C++ ha inventato il concetto di operatori di assegnazioni definibili dall'utente - è possibile scrivere codice specifico per gestire questo caso.

+1

L'ho aumentato perché la lettura mi ha fatto capire l'errore/omissione nella mia risposta. – Clifford

+1

+1 per aver notato che non c'è in realtà alcuna copia in corso. –

+11

Perché questo è stato contrassegnato come spam? Qualcuno ha perso il controllo del proprio mouse? –

13

Questa è una copia semplice, proprio come si farebbe con memcpy() (in effetti, alcuni compilatori in realtà producono una chiamata a memcpy() per quel codice). Non c'è "stringa" in C, solo puntatori a un gruppo di caratteri. Se la tua struttura di origine contiene un tale puntatore, allora il puntatore viene copiato, non gli stessi caratteri.

4

Intendevi "Complesso" come nel numero complesso con parti reali e immaginarie? Questo sembra improbabile, quindi se non dovessi dare un esempio dato che "complesso" significa niente di specifico in termini di linguaggio C.

Si otterrà una copia di memoria diretta della struttura; se questo è ciò che vuoi dipende dalla struttura. Ad esempio se la struttura contiene un puntatore, entrambe le copie punteranno agli stessi dati. Questo può o non può essere quello che vuoi; questo dipende dal design del tuo programma.

Per eseguire una copia "intelligente" (o una copia "profonda"), è necessario implementare una funzione per eseguire la copia. Questo può essere molto difficile da ottenere se la struttura stessa contiene puntatori e strutture che contengono anche dei puntatori e forse dei riferimenti a tali strutture (forse questo è ciò che intendi per "complesso"), ed è difficile da mantenere. La soluzione semplice consiste nell'utilizzare C++ e implementare i costruttori di copia e gli operatori di assegnazione per ogni struttura o classe, quindi ognuno diventa responsabile della propria semantica della copia, è possibile utilizzare la sintassi di assegnazione ed è più facilmente gestibile.

19

primo sguardo a questo esempio:

Il codice C per un semplice programma C è riportata qui sotto

struct Foo { 
    char a; 
    int b; 
    double c; 
    } foo1,foo2; 

void foo_assign(void) 
{ 
    foo1 = foo2; 
} 
int main(/*char *argv[],int argc*/) 
{ 
    foo_assign(); 
return 0; 
} 

l'equivalente codice ASM per foo_assign() è

00401050 <_foo_assign>: 
    401050: 55      push %ebp 
    401051: 89 e5     mov %esp,%ebp 
    401053: a1 20 20 40 00   mov 0x402020,%eax 
    401058: a3 30 20 40 00   mov %eax,0x402030 
    40105d: a1 24 20 40 00   mov 0x402024,%eax 
    401062: a3 34 20 40 00   mov %eax,0x402034 
    401067: a1 28 20 40 00   mov 0x402028,%eax 
    40106c: a3 38 20 40 00   mov %eax,0x402038 
    401071: a1 2c 20 40 00   mov 0x40202c,%eax 
    401076: a3 3c 20 40 00   mov %eax,0x40203c 
    40107b: 5d      pop %ebp 
    40107c: c3      ret  

Come potete vedere, un compito viene semplicemente sostituito da un'istruzione "mov" in assem bly, l'operatore di assegnazione significa semplicemente spostare i dati da una posizione di memoria ad un'altra posizione di memoria. L'assegnazione lo farà solo per i membri immediati di una struttura e non riuscirà a copiare quando si dispone di tipi di dati complessi in una struttura. Qui COMPLEX significa che non puoi avere una serie di puntatori, che puntano agli elenchi.

Un array di caratteri all'interno di una struttura non funzionerà sulla maggior parte dei compilatori, questo perché l'assegnazione semplicemente cercherà di copiare senza nemmeno considerare il tipo di dati di tipo complesso.

+0

Può elaborare su quali condizioni fallirebbe perché sembra funzionare per me sempre –

Problemi correlati