El ejercicio unioncita facilb se encuentra en: https://drive.google.com/file/d/1QRIk3zBGGXH54nSZorX3jnuNmURCHw6K/view?pli=1 > Todos los 'miembros' de la union comparten la misma memoria. Los datos son los mismos pero se interpretan de manera diferente. ```c #include union pruebita { int a; char b; char c[2]; }; int main(){ union pruebita HOLA; HOLA.a = 65; HOLA.c[0] = 'C'; printf("%d\n",HOLA.a); printf("%c\n",HOLA.b); return 0; } ``` A diferencia de las estructuras, donde cada miembro tiene su propia área de memoria, **todos los miembros de una unión comparten la misma dirección**, lo que optimiza el uso de memoria. El tamaño total de la unión es igual al tamaño del miembro más grande. Por ejemplo, al declarar `union { int i; double d; } u;`, se puede acceder a u.i o u.d, pero modificar uno afectará al otro debido a que comparten el mismo espacio en memoria. Esto requiere que el programador tenga cuidado para asegurarse de que solo se accede al miembro correcto en uso. Código generado por IDA: ```c /* This file was generated by the Hex-Rays decompiler version 9.0.0.240807. Copyright (c) 2007-2021 Hex-Rays Detected compiler: Visual C++ */ #include #include #include //------------------------------------------------------------------------- // Function declarations __int64 __fastcall funcion(S *_myun); // unsigned __int64 *__fastcall _local_stdio_printf_options(); idb // unsigned __int64 *__fastcall _local_stdio_scanf_options(); idb int __fastcall vfprintf_l(_iobuf *const _Stream, const char *_Format, __crt_locale_pointers *const _Locale, va_list _ArgList); int __fastcall vfscanf_s_l(_iobuf *const _Stream, const char *_Format, __crt_locale_pointers *const _Locale, va_list _ArgList); int __fastcall main(int argc, const char **argv, const char **envp); __int64 printf(const char *_Format, ...); __int64 scanf_s(const char *_Format, ...); __int64 __fastcall _scrt_initialize_winrt(); __int64 __fastcall get_startup_argv_mode(); char __fastcall _scrt_stub_for_acrt_uninitialize(bool __formal); //------------------------------------------------------------------------- // Data declarations // extern void *(__cdecl *malloc)(size_t Size); // extern void (__cdecl __noreturn *exit)(int Code); // extern int (__cdecl *system)(const char *Command); // extern int (__cdecl *__stdio_common_vfscanf)(unsigned __int64 Options, FILE *Stream, const char *Format, _locale_t Locale, va_list Arglist); // extern FILE *(__cdecl *__acrt_iob_func)(unsigned int Ix); // extern int (__cdecl *__stdio_common_vfprintf)(unsigned __int64 Options, FILE *Stream, const char *Format, _locale_t Locale, va_list ArgList); //----- (0000000140001000) ---------------------------------------------------- __int64 __fastcall funcion(S *_myun) { S resul; // [rsp+20h] [rbp-18h] resul.n = 305419896 - _myun->n; if ( resul.n < 0 ) exit(1); resul.c *= 16; if ( !resul.c ) exit(1); resul.s[1] = _myun->s[0] - _myun->c; return (unsigned int)resul.n; } //----- (00000001400010A0) ---------------------------------------------------- int __fastcall vfprintf_l( _iobuf *const _Stream, const char *_Format, __crt_locale_pointers *const _Locale, va_list _ArgList) { unsigned __int64 *v4; // rax v4 = _local_stdio_printf_options(); return __stdio_common_vfprintf(*v4, _Stream, _Format, _Locale, _ArgList); } //----- (00000001400010F0) ---------------------------------------------------- int __fastcall vfscanf_s_l( _iobuf *const _Stream, const char *_Format, __crt_locale_pointers *const _Locale, va_list _ArgList) { unsigned __int64 *v4; // rax v4 = _local_stdio_scanf_options(); return __stdio_common_vfscanf(*v4 | 1, _Stream, _Format, _Locale, _ArgList); } //----- (0000000140001140) ---------------------------------------------------- int __fastcall main(int argc, const char **argv, const char **envp) { S *my_union; // [rsp+28h] [rbp-10h] my_union = (S *)malloc(4uLL); if ( !my_union ) exit(1); printf("Ingresa un numero\n"); scanf_s("%x", my_union); if ( (unsigned int)funcion(my_union) == 67130096 ) printf("Super Genial\n"); else printf("A estudiar\n"); system("pause"); return 0; } //----- (00000001400011E0) ---------------------------------------------------- __int64 printf(const char *_Format, ...) { _iobuf *v1; // rax va_list va; // [rsp+58h] [rbp+10h] BYREF va_start(va, _Format); v1 = __acrt_iob_func(1u); return (unsigned int)vfprintf_l(v1, _Format, 0LL, va); } //----- (0000000140001260) ---------------------------------------------------- __int64 scanf_s(const char *_Format, ...) { _iobuf *v1; // rax va_list va; // [rsp+58h] [rbp+10h] BYREF va_start(va, _Format); v1 = __acrt_iob_func(0); return (unsigned int)vfscanf_s_l(v1, _Format, 0LL, va); } //----- (0000000140001A70) ---------------------------------------------------- __int64 __fastcall _scrt_initialize_winrt() { return 0LL; } //----- (0000000140001A74) ---------------------------------------------------- __int64 __fastcall get_startup_argv_mode() { return 1LL; } //----- (0000000140001A94) ---------------------------------------------------- char __fastcall _scrt_stub_for_acrt_uninitialize(bool __formal) { return 1; } // nfuncs=76 queued=9 decompiled=9 lumina nreq=0 worse=0 better=0 // ALL OK, 9 function(s) have been successfully decompiled ``` ```c #include #include union UNIONCITA { int n; int c; char s[10]; }; typedef union UNIONCITA S; int funcion(S *_myun) { S resul; // [rsp+20h] [rbp-18h] // result.n tiene que valer 67130096 // Tenés que ingresar un número hexadecimal que restando ese numero resul.n = 305419896 - _myun->n; // 305419896 - x = 67130096 printf("Resultado esperado: 67130096\n"); printf("_myun->n: %d\n",_myun->n); printf("(unsigned int)result.n: %d\n",(unsigned int)resul.n); if ( resul.n < 0 ) exit(1); resul.c *= 16; if ( !resul.c ) exit(1); resul.s[1] = _myun->s[0] - _myun->c; return (unsigned int)resul.n; } int main(int argc, const char **argv, const char **envp) { S *my_union; // [rsp+28h] [rbp-10h] my_union = (S *)malloc(4uLL); if ( !my_union ) exit(1); printf("Ingresa un numero\n"); scanf("%x", my_union); printf ("union: %d\n",my_union->n); printf ("%x\n",funcion(my_union)); printf ("resultado: %d\n", (unsigned int)funcion(my_union)); if ( (unsigned int)funcion(my_union) == 67130096 ) printf("Super Genial\n"); else printf("A estudiar\n"); return 0; } ``` ```c #include #include typedef union { int n; int s[2]; char c; }S; int funcion(S *_myun) { S resul; // [rsp+20h] [rbp-18h] resul.n = 305419896 - _myun->n; if ( resul.n < 0 ) exit(1); printf("%x %x %x %c\n",resul.n,resul.s[0],resul.s[1],resul.c); resul.c *= 16; printf("%x %x %x %c\n",resul.n,resul.s[0],resul.s[1],resul.c); if ( !resul.c ) exit(1); resul.s[1] = _myun->s[0] - _myun->c; return (unsigned int)resul.n; } int main(int argc, const char **argv, const char **envp) { S *my_union; // [rsp+28h] [rbp-10h] my_union = (S *)malloc(4uLL); if ( !my_union ) exit(1); printf("Enter a number\n"); scanf("%x", my_union); if ( funcion(my_union) == 67130096 ) printf("You win\n"); else printf("You lost\n"); return 0; } ```