2010-02-20 18 views
109

¿Se puede asignar una instancia de una estructura a otra, así:Asignar una estructura a otra en C

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

he visto que funcione para estructuras simples, bu funciona para estructuras complejas?
¿Cómo sabe el compilador cómo copiar elementos de datos según su tipo, es decir, diferenciando entre un int y una cadena?

Respuesta

107

Sí, si la estructura es del mismo tipo. Piénselo como una copia de memoria.

+56

Tenga en cuenta que no hay una copia profunda, señalando que la memoria no se copia. –

+2

La simultaneidad también es un problema aquí. –

+12

@Tim La simultaneidad no es más un problema que para la asignación de los tipos incorporados, como los enteros y los dobles; la asignación tampoco es una operación atómica para estos. –

108

Sí, la asignación es compatible con las estructuras. Sin embargo, hay problemas:

struct S { 
    char * p; 
}; 

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

Ahora los punteros de ambas estructuras apuntan al mismo bloque de memoria - el compilador no copia la punta de datos. Ahora es difícil saber qué instancia de estructura posee los datos. Es por esto que C++ inventó el concepto de operadores de asignación definibles por el usuario: puede escribir un código específico para manejar este caso.

+1

Lo aumenté porque leerlo me hizo darme cuenta del error/omisión en mi propia respuesta. – Clifford

+1

+1 para indicar que no hay ninguna copia en curso. –

+11

¿Por qué se marcó como spam? ¿Alguien ha perdido el control de su mouse? –

13

Esta es una copia simple, al igual que lo haría con memcpy() (de hecho, algunos compiladores realmente producen una llamada a memcpy() para ese código). No hay "cadena" en C, solo apunta a un montón de caracteres. Si su estructura fuente contiene dicho puntero, entonces el puntero se copia, no los caracteres en sí.

4

¿Te refieres a "Complejo" como en un número complejo con partes reales e imaginarias? Esto parece improbable, de modo que si no tuvieras que dar un ejemplo, ya que "complejo" no significa nada específico en términos del lenguaje C.

Obtendrá una copia de memoria directa de la estructura; si eso es lo que quieres depende de la estructura. Por ejemplo, si la estructura contiene un puntero, ambas copias apuntarán a los mismos datos. Esto puede o no ser lo que quieres; eso se debe al diseño de tu programa.

Para realizar una copia 'inteligente' (o una copia 'profunda'), deberá implementar una función para realizar la copia. Esto puede ser muy difícil de lograr si la estructura misma contiene punteros y estructuras que también contienen punteros, y quizás punteros a tales estructuras (quizás eso es lo que quiere decir con "complejo"), y es difícil de mantener. La solución simple es usar C++ e implementar constructores de copia y operadores de asignación para cada estructura o clase, luego cada uno se vuelve responsable de su propia semántica de copia, puede usar la sintaxis de asignación y se mantiene más fácilmente.

19

primer vistazo a este ejemplo:

Se da el código C para un programa simple en C por debajo de

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; 
} 

el equivalente Código ASM para foo_assign() es

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  

Como puede ver, una tarea simplemente se reemplaza por una instrucción "mov" en un conjunto bly, el operador de asignación simplemente significa mover datos de una ubicación de memoria a otra ubicación de memoria. La asignación solo lo hará para miembros inmediatos de una estructura y no podrá copiar cuando tenga tipos de datos complejos en una estructura. Aquí COMPLEX significa que no puedes tener una matriz de punteros, apuntando a listas.

Una matriz de caracteres dentro de una estructura no funcionará en la mayoría de los compiladores, esto se debe a que la tarea simplemente intentará copiar sin siquiera considerar que el tipo de datos es de tipo complejo.

+0

¿Puede explicar en qué condiciones fallaría porque parece funcionar para mí? siempre –

Cuestiones relacionadas