Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de...

67
Uniones, campos de bits y enumeraciones

Transcript of Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de...

Page 1: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones, campos de bits y enumeraciones

Page 2: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

Page 3: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

• Una unión es una variable que puede contener (en momentos diferentes) objetos de diferentes tipos y tamaños y,

• Las uniones proporcionan una forma de manipular diferentes clases de datos dentro de una sola área de almacenamiento, sin incluir en el programa ninguna información dependiente de la máquina

Page 4: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

• El propósito de una “unión”: una sola variable que puede legítimamente guardar uno de varios tipos.

• La sintaxis se basa en las estructuras.

• La unión será suficientemente grande como para mantener al mayor de los tipos: el tamaño específico depende de la implantación

Page 5: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

offsetof()

• ANSI C provee una macro (raramente usada) cuya definición está en stddef.h llamada offsetof() que retorna el offset (la distancia en bytes desde el comienzo de la estructura) de un miembro dentro de una estructura o unión; su implementación no es 100% portable

Page 6: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

sizeof()

• No hay que suponer que el tamaño de una estructura es la suma de los tamaños de sus miembros ni que, el tamaño de unión es igual al tamaño del campo más extenso.

• Debido a requisitos de alineación para diferentes objetos, podría haber “huecos” no identificados dentro de una estructura.

Page 7: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

sizeof()

• El operador sizeof regresa el valor apropiado.

• En general, una instancia de una estructura tiene el alineamiento impuesto por el campo o miembro más ancho (en términos de sizeof).

• Los compiladores lo hacen así, como la forma más simple de asegurarse que todos los miembros de la estructura estén auto alineados para obtener un acceso más rápido a los mismos y, que implique menos código de máquina.

Page 8: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejemplo

#include <stdio.h> #include <stddef.h> /* padded union */ union pad { /* occupies 8 bytes */ char c[5]; /* occupies 5 bytes */ float f; /* occupies 4 bytes */ } p; http://www.enseignement.polytechnique.fr/informatique/INF478/docs/Cpp/en/c/language/union.html

Page 9: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejemplo

int main()

{

/* Union members are allocated memory at the same starting address. */

printf("offset of char c[]=%d\noffset of float f = %d\n",offsetof(union pad, c), offsetof(union pad, f));

/* Union pad has 3 bytes of unnamed trailing padding. */

printf("sizeof(union pad) = %d\n", sizeof(union pad)); /* 8 bytes */

printf("sizeof(p.c) = %d\n", sizeof(p.c)); /* 5 bytes */

printf("sizeof(p.f) = %d\n", sizeof(p.f)); /* 4 bytes */

return(0);

}

Page 10: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejemplo

Page 11: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

• Sintácticamente, se tiene acceso a los miembros de una unión con

• Nombre-unión.miembro

• O puntero-unión->miembro

• Precisamente como con una estructura

Page 12: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

• El uso más común de uniones en sistemas embebidos es para permitir un rápido acceso a bytes individuales de un int o long. Un ejemplo podría ser el de contadores de tiempo real de 16 o 32 bits:

union clock { long real_time_count ; // Reservo 4 bytes int real_time_words[2] ; /* Reservo 4 bytes como un array de int*/ char real_time_bytes[4] ; // Reservo 4 bytes un array de char }c;

Page 13: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

• Cualquiera de los tipos de los miembros de la unión puede asignarse a c (variable de tipo union clock) y, luego ser usado en expresiones, mientras que el uso sea consistente:

– el tipo recuperado debe ser el tipo que se almacenó más recientemente

Page 14: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

/* Real Time Interrupt */

void timer0_int(void) {

//en algún lado c estará inicializada con un long

c.real_time_count++ ;//Incrementar clock if(c.real_time_words[1] == 0x8000) {

/* Hacer algo! */ } if(c.real_time_bytes[3] == 0x80) {

/* Hacer algo! */ } }

Page 15: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

• Es responsabilidad del programador llevar el registro del tipo que está almacenado actualmente en una unión;

• si algo se almacena como un tipo y se recupera como otro, el resultado depende de la implantación

• Una unión sólo puede inicializarse con un valor del tipo de su primer miembro, en el ejemplo anterior con un long int

Page 16: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejemplo

#include <stdio.h> union numbers{ int i; float f; }; int main() { union numbers first_number; first_number.i = 5; first_number.f = 3.9; printf("%i%.2f\n",first_number.i,first_number.f); }//se imprime 1081711002 3.90

Page 17: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Inicialización #include <stdio.h>

typedef union

{

char ch;

int flag;

float f;

} data;

int main(){

data d3 = {'B'}; // initialize first member of union

return 0;}

Page 18: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

• Están permitidas las mismas operaciones sobre las uniones como sobre las estructuras: asignación o copia como una unidad, tomar la dirección y, tener acceso a sus miembros.

• Una unión es una estructura en la cual todos los miembros tienen un desplazamiento cero a partir de la base (dirección de comienzo de la unión), la estructura es suficientemente grande para mantener al miembro “más ancho” y, la alineación es la apropiada para todos los tipos de la unión.

Page 19: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

• Las uniones pueden presentarse dentro de estructuras y arreglos y, viceversa.

• La notación para tener acceso a un miembro de una unión en una estructura (o viceversa) es idéntica a la de las estructuras anidadas.

• Por ejemplo, dos formas distintas de representar una fecha del presente año:

Page 20: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

/*A modo de ejemplo para apreciar cómo se accede a los miembros de una unión que anida una estructura*/ typedef union {//unión anónima char date[25]; struct {//estructura anónima short int month; short int day; } dayValues; } DAY; http://www.technoplaza.net/programming/lesson7p3.php

Page 21: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones

#define YEAR 2020 const char *nombresmes[] = {"enero","febrero","marzo","abril","mayo","junio", "julio","agosto","septiembre","octubre", "noviembre","diciembre"}; //convierte fechas numéricas de un array de DAY, a formato string void convertDays(DAY *days, int cantfechas) { int loop, cantfechas; short int dia, mes; // ciclo a través de los días del array y almaceno la fecha como string for (loop = 0; loop < cantfechas; loop++) { dia = days[loop].dayValues.dia; mes = days[loop].dayValues.mes; sprintf(days[loop].fecha,"%s %d, %d",nombresmes[mes],dia,YEAR); }}

Page 22: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones anónimas

Page 23: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones anónimas

• Los nombres de los miembros tienen alcance fuera de la unión o estructura

• Las estructuras y uniones anónimas son de utilidad para manipular los registros del procesador que están mapeados en direcciones de memoria. Por ejemplo: del archivo MKL46Z4.h

Page 24: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones anónimas

Page 25: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejercicio 7

Page 26: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Endianness

Page 27: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Endianness

• Se denomina endianness al atributo de un sistema que indica si un dato multibyte (por ejemplo, enteros, flotantes, etc.) se almacena en memoria con su byte más significativo en las direcciones de memoria más bajas o en las más altas.

• En el primer caso se dice que la arquitectura del procesador es de tipo big endian y en el segundo se trata de una tipo little endian.

Page 28: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Endianness

• El problema es similar a los idiomas en los que se escriben de derecha a izquierda, como el árabe, o el hebreo, frente a los que se escriben de izquierda a derecha pero, trasladado de la escritura al almacenamiento en memoria de los bytes.

Page 29: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el
Page 30: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Endianness

• Usando este criterio el sistema big-endian adoptado por Motorola y en la mayoría de las arquitecturas RISC, consiste en representar los bytes en el orden "natural": así el valor hexadecimal 0x4A3B2C1D se codificaría en memoria en la secuencia {4A, 3B, 2C, 1D}.

• En el sistema little-endian adoptado por Intel y varias plataformas con arquitecturas CISC, el mismo valor se codificaría como {1D, 2C, 3B, 4A}, de manera que de este modo se hace más intuitivo el acceso a datos, porque se efectúa fácilmente de manera incremental de menos relevante a más relevante

Page 31: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Endianness

• Todos los Cortex ARM, en la práctica son Little-endian, incluso Freescale (hoy NXP, ex Motorola), eligió Little Endian para su familia Kinetis, sin embargo existen otras arquitecturas de 32 bits que usan big-endian

Page 32: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Endianness

• Una forma sencilla de determinar la endianness, consiste en chequear la disposición en memoria de una constante predefinida.

• Se sabe que la disposición de una variable de 32 bits de valor 1 es 00 00 00 01 (en hexadecimal) en big-endian and 01 00 00 00 para little-endian. Por tanto, podemos escribir

const int i = 1;

#define is_bigendian() ((*(char*)&i)== 0)

Page 33: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el
Page 34: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el
Page 35: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejercicio 7

typedef union byte {//ejercicio práctica

short int si;

int i;

long long int lli;

float f;

double d;

unsigned long long int ulli;

unsigned char bytes[10];

} Bytes;

Page 36: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejercicio 7 #include <stdio.h> #include <stdlib.h> #include <stddef.h> void main(){ char buffer[17]; short int intCor = 29813; // Entero corto 16 bits. Bytes b; int i, tam; itoa(intCor,buffer,16);//como hexadecimal y string printf(“29813 en Hexadecimal: %s\n",buffer); itoa(intCor,buffer,2);//como binario y string printf(“En Binario: %s\n",buffer); b.si=intCor; printf("La direccion de la union es: %p\n",&b); tam= sizeof( b.si ); for(i=0;i<tam;i++){ printf("Byte %d: %x\n",i,b.bytes[i]); printf("Offset of 'bytes[%d] is %u\n", i,offsetof(Bytes, bytes[i])); } }

Page 37: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejercicio 7

29813 en Hexadecimal: 7475

En Binario 111010001110101

La direccion de la union es: 0061FF10

Byte 0: 75

Offset of 'bytes[0] is 0

Byte 1: 74

Offset of 'bytes[1] is 1

Page 38: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Enumeraciones

Page 39: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Enumeraciones

• Una enumeración es una lista de valores enteros constantes, como en

• enum boolean {NO, YES};

• El primer nombre en un enum tiene el valor 0, el siguiente 1 y, así sucesivamente, a menos que sean especificados valores explícitos.

• Proveen una manera conveniente de asociar valores constantes con nombre, alternativas a usar varias macros con #define, con la ventaja de que el compilador asigna valores automáticamente y con enum se siguen las reglas con respecto al ámbito

Page 40: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Enumeraciones

• Sino se especifican todos los valores, aquéllos no especificados continúan la progresión a partir del último valor que sí lo fue, como en el 2º de estos ejemplos:

• enum escapes {BELL=‘\a’, RETROCESO=‘\b’, TAB=‘\t’, NVALIN=‘\n’, VTAB=‘\v’, RETURN=‘\r’};

• enum months {ENE=1, FEB, MAR, ABR, MAY, JUN, JUL, AGO, SEP, OCT, NOV, DIC};

• /*FEB es 2, MAR es 3, etc.*/

Page 41: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Enumeraciones

• Los valores no necesitan ser distintos dentro de la misma enumeración.

• Los nombres que están en enumeraciones distintas deben ser distintos

• En la práctica se utilizan mucho para definir constantes simbólicas en una sentencia switch

• El debugger puede imprimir los nombres de las constantes

Page 42: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Enumeraciones

• En el ejemplo anterior:

enum months m=ENE;

• Usando typedef:

• typedef enum months {ENE=1, FEB, MAR, ABR, MAY, JUN, JUL, AGO, SEP, OCT, NOV, DIC}Months;

• Months m=ENE;

Page 43: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Enumeraciones

• Ejercicio 11: Un dispositivo de comunicaciones puede utilizar una velocidad de transferencia de 1200, 2400, 4800, y 9600 baudios. Definir un tipo enumerativo que modelice dicha situación.

• typedef enum vt {v1=1200,v2=2400,v3=4800,v4=9600}VT;

Page 44: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Enumeraciones

Page 45: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Enumeraciones anónimas

• enum {off, on};

• Estas constantes pueden referenciarse en la misma forma que las constantes regulares

• int switch=off;

• typedef enum {/*anónima*/

red,

yellow,

green

} LightForCars;

Page 46: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones con enumeraciones

• Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el miembro activo de la unión, a este tipo de estructura se lo suele llamar unión discriminada o etiquetada (tagged).

• La etiqueta normalmente es una enumeración aunque podría ser un tipo integral. Veamos el siguiente ejemplo ilustrativo

Page 47: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones con enumeraciones

typedef struct flight { enum { PASSENGER, CARGO } type;/*vuelo de pasajeros o de cargas*/ union { int npassengers;//nro.de pasajeros double tonnages; /* las unidades de carga, pueden no ser toneladas*/ }cargo; } Flight; Flight flights[ 1000 ]; flights[ 42 ].type = PASSENGER; flights[ 42 ].cargo.npassengers = 150; flights[ 20 ].type = CARGO; flights[ 20 ].cargo.tonnages = 356.78;

Page 48: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

• Cuando el espacio de almacenamiento es escaso, puede ser necesario empaquetar varios objetos dentro de una sola palabra de máquina; un uso común es un conjunto de banderas de un bit como typedef struct permisos {

unsigned int lectura :1;//almaceno 0 o 1

unsigned int escritura :1;

unsigned int ejecucion :1;

} permisos_t;

Page 49: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

• Un campo de bits, o simplemente campo, es un conjunto de bits adyacentes dentro de una unidad de almacenamiento definida por la implantación, al que llamaremos “palabra”.

• La sintaxis para la definición y acceso a campos está basada en estructuras

Page 50: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

• En el ejemplo se define una variable llamada permisos_t que contiene tres campos de un bit.

• El número que sigue al carácter dos puntos (:) representa el ancho del campo en bits.

• Los campos son declarados unsigned int para asegurar que sean cantidades sin signo.

• Los campos individuales son referidos en la misma forma que para otros miembros de estructuras.

• Los campos se comportan como pequeños enteros y pueden participar en expresiones aritméticas, como lo hacen otros enteros

Page 51: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

• En el ejercicio 9 se pide usar un campo de bits para qué tipo de características tiene la comunicación en una red de sensores inalámbrica y, si se pudo establecer o no, dicha comunicación. La comunicación puede ser broadcast o unicast, multihop o single hop, el mensaje se puede enviar o puede fallar su envío, y el mismo puede ser recibido o no.

• Significado de cada bit:0 broadcast, 1 unicast, 2 multihop, 3 single hop, 4 enviado, 5 no enviado, 6 recibido y 7 no recibido.

Page 52: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

typedef struct comunicacion { unsigned char broadcast:1; unsigned char unicast:1; unsigned char multihop:1; unsigned char singlehop:1; unsigned char enviado:1; unsigned char noenviado:1; unsigned char recibido:1; unsigned char norecibido:1; } Comunica;

Page 53: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

Comunica c;

int n=rand() % 2;

c.broadcast = n;

if( n == 0 )

c.unicast = 1;

else

c.unicast = 0;

Page 54: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

• Casi todo acerca de los campos es dependiente de la implantación. El que un campo pueda traspasar el límite de una palabra se define por la implantación.

• Ídem si los campos se asignan de izquierda a derecha o, al revés

• La única solución portable es operaciones a nivel de bits (máscaras) en lugar de campos de bits, son más eficientes y permiten manipular más de un bit a la vez, en una misma instrucción

Page 55: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

• Los campos no necesitan tener nombres; los campos sin nombre (dos puntos y su amplitud solamente) se emplean para llenar espacios o para obtener alineamiento.

• El ancho especial 0 puede emplearse para obligar a la alineación al siguiente límite de palabra

Page 56: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

• La mayoría de los registros de hardware o protocolos de comunicaciones suelen tener “huecos” de bits no usados o reservados

Page 57: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

• Pruebe código de: https://aticleworld.com/bit-field-in-c/ donde hay muchos ejemplos donde se muestran muchas cuestiones dependientes de la implementación

• Por ejemplo,

Page 58: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

Page 59: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

Page 60: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Campos de bits

• Los campos sólo se pueden declarar como algún tipo de entero; por portabilidad, se debe especificar explícitamente si son signed o unsigned, salvo los de longitud uno que, sólo pueden ser unsigned.

• No son arreglos y no tienen direcciones, de modo que el operador & no puede aplicarse a ellos

• Normalmente se usan uniones conjuntamente con campos de bits para representar y acceder a los registros de hardware, hacer el código más portable permitiendo el acceso al registro completo

Page 61: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones con campos de bits

Page 62: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones con campos de bits

• Son de utilidad para definir variables booleanas ahorrando memoria

Page 63: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones con campos de bits

Page 64: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Uniones con campos de bits

• Ejercicio 8: Cree un campo de bits (representando un byte bit a bit) y, una unión que contenga dicho campo además de, otro que permita representar el código ASCII de un caracter,

• de forma de poder utilizarlos en una función que, recibiendo como argumento una cadena de caracteres, cambie en cada carácter de la misma, los bits que ocupan las posiciones pares (cambie de 0 a 1 o de 1 a 0).

• La función deberá retornar la cadena de caracteres modificada. Por ejemplo si la cadena de caracteres pasada como argumento contiene un carácter ‘a’ (código ASCII=97, en binario: 01100001), conmutando los bits 0, 2, 4 y 6, en binario tengo 00110100 o, en decimal: 52 que corresponde a ‘4’.

Page 65: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejercicio 8

#include <stdio.h> #include <string.h> #include <stdlib.h> typedef union ascii{//ejercicio de la práctica unsigned int c;//almaceno código ASCII de un char struct{ unsigned char bit0:1; unsigned char bit1:1; unsigned char bit2:1; unsigned char bit3:1; unsigned char bit4:1; unsigned char bit5:1; unsigned char bit6:1; unsigned char bit7:1;}A; }Ascii;

Page 66: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejercicio 8

//modifica bits de las posiciones pares char* modificapares(char* s){ int n=strlen(s),i; char *p=(char*)malloc(n+1); Ascii as; strcpy(p,s); for(i=0;i<n;i++){ as.c=s[i];//almaceno el caracter en un byte (0-255) as.A.bit0=~as.A.bit0;//accedo a los bits de ese char as.A.bit2=~as.A.bit2; as.A.bit4=~as.A.bit4; as.A.bit6=~as.A.bit6; p[i]=as.c;} return p; }

Page 67: Uniones, campos de bits y enumeraciones · Uniones con enumeraciones •Es muy común el uso de uniones emparejado con un valor discreto (discriminador o etiqueta) que indique el

Ejercicio 8

int main(){

char frase[]="Hola mundo";

char *p=modificapares(frase);

printf("%s\n",p);

//se imprime :94u8 ;1:

return 0;

}