palabras conjuntos c++ c struct unions

c++ - conjuntos - ¿Cuál es la principal diferencia entre "unión" y "estructura" en C.?



union de conjuntos c++ (7)

Posible duplicado:
Diferencia entre una estructura y una unión en C

Pude entender lo que significa una estructura. Pero, estoy un poco confundido con la diferencia entre unión y estructura. La unión es como compartir la memoria. ¿Qué significa exactamente?


Cada miembro de un sindicato comparte la misma memoria. Eso significa que si cambias uno, cambias los otros. Y si los miembros son de diferentes tipos, esto puede tener resultados impredecibles. (No es exactamente impredecible, pero es difícil de predecir a menos que sea consciente de los patrones de bits subyacentes que conforman los miembros de los datos).


Con un sindicato, todos los miembros comparten la misma memoria. Con una estructura, no comparten memoria, por lo que se asigna un espacio diferente en la memoria a cada miembro de la estructura.

Por ejemplo:

union foo { int x; int y; }; foo f; f.x = 10; printf("%d/n", f.y);

Aquí, asignamos el valor de 10 a foo::x . Luego emitimos el valor de foo::y , que también es 10, ya que xey comparten la misma memoria. Tenga en cuenta que dado que todos los miembros de una unión comparten la misma memoria, el compilador debe asignar suficiente memoria para que quepa el miembro más grande de la unión. Por lo tanto, una unión que contenga un char y un long necesitaría suficiente espacio para adaptarse al long .

Pero si usamos una estructura:

struct foo { int x; int y; }; foo f; f.x = 10; f.y = 20; printf("%d %d/n", f.x, f.y);

Asignamos 10 a x y 20 a y, y luego imprimimos ambos. Vemos que x es 10 e y es 20, porque xey no comparten la misma memoria.

EDITAR: También tome nota del comentario de Gman arriba. El ejemplo que proporcioné con el sindicato es solo para fines de demostración. En la práctica, no debe escribir en un miembro de datos de una unión y luego acceder a otro miembro de datos. Por lo general, esto simplemente hará que el compilador interprete el patrón de bits como otro tipo, pero es posible que obtenga resultados inesperados ya que hacerlo es un comportamiento indefinido .


Ejecuta este programa y descubre la salida.

#include <stdio.h>

int main() { union _testUnion { long long x; long long y; } testUnion; struct _testStruct { long long x; long long y; }testStruct; printf("Sizeof Union %d/n",sizeof(testUnion)); printf("Sizeof Struct %d/n",sizeof(testStruct)); return; }

Encontrará que el tamaño de la estructura es el doble que el de la unión. Esto se debe a que la unión ha asignado espacio para una sola variable, mientras que struct ha asignado para dos.


He usado uniones para convertir bytes hacia y desde otros tipos. Me parece más fácil que el cambio de bits.

union intConverter { int intValue; struct { byte hi; byte lo; } byteValue; } intConverter cv; cv.intValue =1100; printf("%X %X/n", cv.byteValue.hi, cv.byteValue.lo);

Donde int es de 16 bits (se usó en un microcontrolador).


La mayoría de las respuestas aquí son correctas. Una unión es esencialmente una forma de acceder a los mismos datos de diferentes maneras (por ejemplo, puede acceder / interpretar 4 bytes de memoria como 1 entero, o como 4 caracteres). Las estructuras que usted conoce son sencillas: una colección de diferentes objetos separados con su propia memoria.

Por lo general, se requieren Uniones en una etapa muy posterior en la programación en comparación con Estructuras.


Puede ser más útil tener un ejemplo no controlado de para qué sirve esto. (Digo "no motivado" porque la mayoría de los usos de la unión de bit banging son extremadamente traicioneros. Las uniones de bit banging tomadas de big-endian a little-endian hardware se rompen de la manera más desconcertante (inicialmente).) (Por supuesto, he uniones de bit banging escritas para separar números de punto flotante para implementar funciones matemáticas de órdenes de magnitud más rápidas que la biblioteca. Solo agrego afirmaciones sobre qué miembros se supone que tienen las mismas direcciones.)

struct option1 { int type; /* other members */ }; struct option2 { int type; /* other members */ }; struct option3 { int type; /* other members */ }; union combo { int type; // guaranteed to exactly overlap with the structs'' ints type. struct option1; struct option2; struct option3; }; // ... void foo(union combo *in) { switch(in.type) { case 1: { struct option1 *bar = in; //then process an option1 type of request } case 2: { struct option2 *bar = in; //then process an option2 type of request } case 3: { struct option3 *bar = in; //then process an option3 type of request } }

Este tipo de construcción es muy común en la programación X y en otras situaciones en las que se desea realizar una función que pueda recibir muchos tipos diferentes de mensajes (con diferentes argumentos y requisitos de diseño).


Supongo que una forma de pensar en una unión es que es un conjunto de alias de tipo variable a un bloque de memoria donde cada miembro de la unión es un "alias" con un tipo dado. Cada alias se refiere a la misma dirección en la memoria. La forma en que se interpretan los bits en esa dirección se determina por el tipo de alias.

La cantidad de memoria que ocupa la unión es siempre igual o posiblemente mayor que el "miembro" de mayor tamaño de la unión (debido a restricciones de alineación).