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.
#include <stdio.h>
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:
/* This file was generated by the Hex-Rays decompiler version 9.0.0.240807.
Copyright (c) 2007-2021 Hex-Rays <info@hex-rays.com>
Detected compiler: Visual C++
*/
#include <windows.h>
#include <defs.h>
#include <stdarg.h>
//-------------------------------------------------------------------------
// 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
#include <stdio.h>
#include <stdlib.h>
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;
}
#include <stdio.h>
#include <stdlib.h>
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;
}