![]() |
| |||
| Hola a todos: Tengo un pequeño problema con campos de bit. El caso es que necesito que en un archivo se guarden datos con un número específico de bits, y para ello pensé utilizar los campos de bit, que me parecieron una alternativa más lógica que hacer desplazamientos y máscaras para conseguir poner los valores adecuados. Definí la estructura, e hice la prueba con algunos valores. Así, los escribe en un archivo, luego lee del archivo, y me los muestra en pantalla. Perfecto. Sin embargo, y dado que luego ese archivo tendrá que tratarlo otra aplicación, me puse a curiosear en el archivo que se había creado. El resultado fue que no coincidía con lo que tendría que ser, con lo que me surgen varias dudas: - ¿Cómo se almacenan estos campos de bit realmente? - ¿Por qué, si inicializo los campos a 0, no guarda ceros en el archivo, en las posiciones donde no he escrito otra cosa? El código es el siguiente: bits.h: #ifndef _BITS_ #define _BITS_ typedef struct sPrincipal{ unsigned int total:8; unsigned int ano:7; unsigned int tiempo:20; unsigned int seD:8; unsigned int numSat:4; unsigned int edadP:1; signed int latitud:32; signed int longitud:32; unsigned int velocidad:6; unsigned int ignicion:1; unsigned int movimiento:1; unsigned int distancia:23; } tipoPrincipal; typedef struct sIncremental{ unsigned int incTiempo:11; unsigned int seD:8; unsigned int numSat:4; unsigned int edadP:1; signed int incLatitud:18; signed int incLongitud:18; unsigned int velocidad:6; unsigned int ignicion:1; unsigned int movimiento:1; unsigned int incDistancia:16; } tipoIncremental; typedef struct sRegHco{ tipoPrincipal Principal; tipoIncremental Incremental[15]; } tipoRegHco; void copiarEstructura(tipoRegHco,tipoRegHco *); void inicializarEstructura(tipoRegHco *); #endif bits.cpp: #include "bits.h" void copiarEstructura(tipoRegHco reg1,tipoRegHco *reg2){ (*reg2).Principal.total=reg1.Principal.total; (*reg2).Principal.ano=reg1.Principal.ano; (*reg2).Principal.tiempo=reg1.Principal.tiempo; (*reg2).Principal.seD=reg1.Principal.seD; (*reg2).Principal.numSat=reg1.Principal.numSat; (*reg2).Principal.edadP=reg1.Principal.edadP; (*reg2).Principal.latitud=reg1.Principal.latitud; (*reg2).Principal.longitud=reg1.Principal.longitud ; (*reg2).Principal.velocidad=reg1.Principal.velocid ad; (*reg2).Principal.ignicion=reg1.Principal.ignicion ; (*reg2).Principal.movimiento=reg1.Principal.movimi ento; (*reg2).Principal.distancia=reg1.Principal.distanc ia; for(short i=0;i<15;i++){ (*reg2).Incremental[i].incTiempo=reg1.Incremental[i].incTiempo; (*reg2).Incremental[i].seD=reg1.Incremental[i].seD; (*reg2).Incremental[i].numSat=reg1.Incremental[i].numSat; (*reg2).Incremental[i].edadP=reg1.Incremental[i].edadP; (*reg2).Incremental[i].incLatitud=reg1.Incremental[i].incLatitud; (*reg2).Incremental[i].incLongitud=reg1.Incremental[i].incLongitud; (*reg2).Incremental[i].velocidad=reg1.Incremental[i].velocidad; (*reg2).Incremental[i].ignicion=reg1.Incremental[i].ignicion; (*reg2).Incremental[i].movimiento=reg1.Incremental[i].movimiento; (*reg2).Incremental[i].incDistancia=reg1.Incremental[i].incDistancia; } } void inicializarEstructura(tipoRegHco *reg){ (*reg).Principal.total=0; (*reg).Principal.ano=0; (*reg).Principal.tiempo=0; (*reg).Principal.seD=0; (*reg).Principal.numSat=0; (*reg).Principal.edadP=0; (*reg).Principal.latitud=0; (*reg).Principal.longitud=0; (*reg).Principal.velocidad=0; (*reg).Principal.ignicion=0; (*reg).Principal.movimiento=0; (*reg).Principal.distancia=0; for(short i=0;i<15;i++){ (*reg).Incremental[i].incTiempo=0; (*reg).Incremental[i].seD=0; (*reg).Incremental[i].numSat=0; (*reg).Incremental[i].edadP=0; (*reg).Incremental[i].incLatitud=0; (*reg).Incremental[i].incLongitud=0; (*reg).Incremental[i].velocidad=0; (*reg).Incremental[i].ignicion=0; (*reg).Incremental[i].movimiento=0; (*reg).Incremental[i].incDistancia=0; } } pruebaBits.cpp: #include <stdio.h> #include <stdlib.h> #include "bits.h" FILE *fichero; size_t tamano; tipoRegHco Registro; tipoRegHco *RegGuardar=NULL; tipoRegHco RegHco[744]; int main(int argc, char* argv[]) { for(int i=0;i<744;i++){ inicializarEstructura(&RegHco[i]); } RegHco[0].Principal.total=2; RegHco[0].Principal.ano=26; RegHco[0].Principal.tiempo=3; RegHco[0].Principal.seD=0; RegHco[0].Principal.numSat=3; RegHco[0].Principal.edadP=1; RegHco[0].Principal.latitud=4234567; RegHco[0].Principal.longitud=-365432; RegHco[0].Principal.velocidad=60; RegHco[0].Principal.ignicion=1; RegHco[0].Principal.movimiento=0; RegHco[0].Principal.distancia=100; RegHco[0].Incremental[0].incTiempo=1000; RegHco[0].Incremental[0].seD=0; RegHco[0].Incremental[0].numSat=10; RegHco[0].Incremental[0].edadP=1; RegHco[0].Incremental[0].incLatitud=-1000; RegHco[0].Incremental[0].incLongitud=1000; RegHco[0].Incremental[0].velocidad=62; RegHco[0].Incremental[0].ignicion=0; RegHco[0].Incremental[0].movimiento=1; RegHco[0].Incremental[0].incDistancia=1000; RegGuardar=new struct sRegHco[1]; //RegGuardar[0]=RegHco[0]; /* RegGuardar[0].Principal.total=RegHco[0].Principal.total; RegGuardar[0].Principal.ano=RegHco[0].Principal.ano; RegGuardar[0].Principal.tiempo=RegHco[0].Principal.tiempo; RegGuardar[0].Principal.seD=RegHco[0].Principal.seD; RegGuardar[0].Principal.numSat=RegHco[0].Principal.numSat; RegGuardar[0].Principal.edadP=RegHco[0].Principal.edadP; RegGuardar[0].Principal.latitud=RegHco[0].Principal.latitud; RegGuardar[0].Principal.longitud=RegHco[0].Principal.longitud; RegGuardar[0].Principal.velocidad=RegHco[0].Principal.velocidad; RegGuardar[0].Principal.ignicion=RegHco[0].Principal.ignicion; RegGuardar[0].Principal.movimiento=RegHco[0].Principal.movimiento; RegGuardar[0].Principal.distancia=RegHco[0].Principal.distancia; RegGuardar[0].Incremental[0].incTiempo=RegHco[0].Incremental[0].incTiempo; RegGuardar[0].Incremental[0].seD=RegHco[0].Incremental[0].seD; RegGuardar[0].Incremental[0].numSat=RegHco[0].Incremental[0].numSat; RegGuardar[0].Incremental[0].edadP=RegHco[0].Incremental[0].edadP; RegGuardar[0].Incremental[0].incLatitud=RegHco[0].Incremental[0].incLatitud; RegGuardar[0].Incremental[0].incLongitud=RegHco[0].Incremental[0].incLongitud; RegGuardar[0].Incremental[0].velocidad=RegHco[0].Incremental[0].velocidad; RegGuardar[0].Incremental[0].ignicion=RegHco[0].Incremental[0].ignicion; RegGuardar[0].Incremental[0].movimiento=RegHco[0].Incremental[0].movimiento; RegGuardar[0].Incremental[0].incDistancia=RegHco[0].Incremental[0].incDistancia;*/ copiarEstructura(RegHco[0],&RegGuardar[0]); fichero=fopen("pruebaBits.dat", "w+b"); tamano=fwrite(RegGuardar,sizeof(*RegGuardar),1,fic hero), fclose(fichero); printf("El tamaño es: %d\n",tamano); delete(RegGuardar); fichero=fopen("pruebabits.dat","rb"); tamano=fread(&Registro,sizeof(Registro),1,fichero) ; fclose(fichero); printf("El tamaño leído es: %d\n",tamano); printf("Total: %d\n",Registro.Principal.total); printf("Año: %d\n",Registro.Principal.ano); printf("Tiempo: %d\n",Registro.Principal.tiempo); printf("Distancia: %d\n",Registro.Principal.distancia); printf("Latitud y Longitud: %d, %d\n",Registro.Principal.latitud,Registro.Principa l.longitud); printf("incTiempo: %d\n",Registro.Incremental[0].incTiempo); printf("incDistancia: %d\n",Registro.Incremental[0].incDistancia); printf("incLatitud e incLongitud: %d, %d\n",Registro.Incremental[0].incLatitud,Registro.Incremental[0].incLongitud); return 0; } El archivo que se crea es el siguiente: 0000000: 029a cdcd 0300 0030 cdcd cdcd 479d 4000 .......0....G.***. 0000010: 886c faff 7c64 0080 e803 d0cd 18fc cfcd .l..|d.......... 0000020: e803 f8ce e803 cdcd 0000 00cd 0000 cccd ................ 0000030: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 0000040: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 0000050: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 0000060: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 0000070: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 0000080: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 0000090: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 00000a0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 00000b0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 00000c0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 00000d0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 00000e0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 00000f0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ 0000100: 0000 00cc 0000 cdcd 0d0a .......... Que, traducido a binario, si no me he equivocado, sería: 00000010100110101100110111001101000000110000000000 00000000110000110011011100110111001101110011010100 0111100111010100000000000000 10001000011011001111101011111111011111000110010000 00000010000000111010000000001111010000110011010001 1000111111001100111111001101 11101000000000111111100011001110111010000000001111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 11001101110011011100110111001101110011011100110111 001101110011010000110100001010 Sin embargo, para los valores que le doy, se supone que la primera línea debería ser (igualmente, si no me he equivocado): 00000010001101000000000000000000011000000000011100 00000001000000100111010100011110000000000001011001 0011011110001111001000000000000000001100100 Cosa que no coincide. De ahí, mis dudas. Espero que podáis ayudarme. Un saludo y muchas gracias. |
| | ||||
| ||||
| |
| |||
| Hola lestat_l: No he probado el programa porque no dispongo de mucho tiempo, pero yo diría que estás presuponiendo cómo debe ser la representación de la clase por parte de tu compilador y eso no es una postura correcta. La disposición en memoria de los atributos no está estipulada y dependerá de tu entorno, así como la representación en memoria de los valores de tales atributos depende del entorno de ejecución. Entiendo que estás presuponiendo que el compilador asigna el número especificado de bits por cada campo y luego pone uno tras otro. Yo creo que no es así, sino que por cuestión de la arquitectura de tu máquina, asigna en bloques de byte. Con lo que si tu tienes un campo del tipo: campo1:8 Te ocupa 8 bits Pero si tienes un campo del tipo: campo2:7 Te ocupa también 8 bits Y si tienes un campo del tipo: campo3:20 Te ocupa 24 bits Por lo que veo en el resultado, los valores parecen ajustados a la derecha en tal representación. Otra pregunta sería: ¿que hace con los bits sobrantes? A mi me parece que su valor es indefinido (lo que hubiera en memoria en el momento de la asignación). Creo que es basura y que simplemente no lo trata (descarta esos bits sobrantes). La razón de que sean múltiplos de 8 en tu plataforma, o de 16, 32, 64 (en otras), es cuestión de eficiencia, porque de lo contrario, por cada operación de asignación que hicieras, tendría que hacer el ordenador lo que tu no haces (aplicar máscaras, etc...), y es mucho más rápido, almacenarlo en bloques de tamaño que maneje el ordenador. Un saludo. Espero que te haya sido de ayuda lestat_l wrote: > Hola a todos: > > Tengo un pequeño problema con campos de bit. El caso es que necesito > que en un archivo se guarden datos con un número específico de bits, > y para ello pensé utilizar los campos de bit, que me parecieron una > alternativa más lógica que hacer desplazamientos y máscaras para > conseguir poner los valores adecuados. > > Definí la estructura, e hice la prueba con algunos valores. Así, los > escribe en un archivo, luego lee del archivo, y me los muestra en > pantalla. Perfecto. > > Sin embargo, y dado que luego ese archivo tendrá que tratarlo otra > aplicación, me puse a curiosear en el archivo que se había creado. El > resultado fue que no coincidía con lo que tendría que ser, con lo que > me surgen varias dudas: > > - ¿Cómo se almacenan estos campos de bit realmente? > - ¿Por qué, si inicializo los campos a 0, no guarda ceros en el > archivo, en las posiciones donde no he escrito otra cosa? > > El código es el siguiente: > > bits.h: > > #ifndef _BITS_ > #define _BITS_ > > typedef struct sPrincipal{ > unsigned int total:8; > unsigned int ano:7; > unsigned int tiempo:20; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int latitud:32; > signed int longitud:32; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int distancia:23; > } tipoPrincipal; > > typedef struct sIncremental{ > unsigned int incTiempo:11; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int incLatitud:18; > signed int incLongitud:18; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int incDistancia:16; > } tipoIncremental; > > typedef struct sRegHco{ > tipoPrincipal Principal; > tipoIncremental Incremental[15]; > } tipoRegHco; > > void copiarEstructura(tipoRegHco,tipoRegHco *); > void inicializarEstructura(tipoRegHco *); > > #endif > > bits.cpp: > > #include "bits.h" > > void copiarEstructura(tipoRegHco reg1,tipoRegHco *reg2){ > (*reg2).Principal.total=reg1.Principal.total; > (*reg2).Principal.ano=reg1.Principal.ano; > (*reg2).Principal.tiempo=reg1.Principal.tiempo; > (*reg2).Principal.seD=reg1.Principal.seD; > (*reg2).Principal.numSat=reg1.Principal.numSat; > (*reg2).Principal.edadP=reg1.Principal.edadP; > (*reg2).Principal.latitud=reg1.Principal.latitud; > (*reg2).Principal.longitud=reg1.Principal.longitud ; > (*reg2).Principal.velocidad=reg1.Principal.velocid ad; > (*reg2).Principal.ignicion=reg1.Principal.ignicion ; > (*reg2).Principal.movimiento=reg1.Principal.movimi ento; > (*reg2).Principal.distancia=reg1.Principal.distanc ia; > > for(short i=0;i<15;i++){ > (*reg2).Incremental[i].incTiempo=reg1.Incremental[i].incTiempo; > (*reg2).Incremental[i].seD=reg1.Incremental[i].seD; > (*reg2).Incremental[i].numSat=reg1.Incremental[i].numSat; > (*reg2).Incremental[i].edadP=reg1.Incremental[i].edadP; > (*reg2).Incremental[i].incLatitud=reg1.Incremental[i].incLatitud; > (*reg2).Incremental[i].incLongitud=reg1.Incremental[i].incLongitud; > (*reg2).Incremental[i].velocidad=reg1.Incremental[i].velocidad; > (*reg2).Incremental[i].ignicion=reg1.Incremental[i].ignicion; > (*reg2).Incremental[i].movimiento=reg1.Incremental[i].movimiento; > (*reg2).Incremental[i].incDistancia=reg1.Incremental[i].incDistancia; > } > } > > void inicializarEstructura(tipoRegHco *reg){ > (*reg).Principal.total=0; > (*reg).Principal.ano=0; > (*reg).Principal.tiempo=0; > (*reg).Principal.seD=0; > (*reg).Principal.numSat=0; > (*reg).Principal.edadP=0; > (*reg).Principal.latitud=0; > (*reg).Principal.longitud=0; > (*reg).Principal.velocidad=0; > (*reg).Principal.ignicion=0; > (*reg).Principal.movimiento=0; > (*reg).Principal.distancia=0; > > for(short i=0;i<15;i++){ > (*reg).Incremental[i].incTiempo=0; > (*reg).Incremental[i].seD=0; > (*reg).Incremental[i].numSat=0; > (*reg).Incremental[i].edadP=0; > (*reg).Incremental[i].incLatitud=0; > (*reg).Incremental[i].incLongitud=0; > (*reg).Incremental[i].velocidad=0; > (*reg).Incremental[i].ignicion=0; > (*reg).Incremental[i].movimiento=0; > (*reg).Incremental[i].incDistancia=0; > } > } > > pruebaBits.cpp: > > #include <stdio.h> > #include <stdlib.h> > #include "bits.h" > > FILE *fichero; > size_t tamano; > tipoRegHco Registro; > tipoRegHco *RegGuardar=NULL; > tipoRegHco RegHco[744]; > > int main(int argc, char* argv[]) > { > for(int i=0;i<744;i++){ > inicializarEstructura(&RegHco[i]); > } > > RegHco[0].Principal.total=2; > RegHco[0].Principal.ano=26; > RegHco[0].Principal.tiempo=3; > RegHco[0].Principal.seD=0; > RegHco[0].Principal.numSat=3; > RegHco[0].Principal.edadP=1; > RegHco[0].Principal.latitud=4234567; > RegHco[0].Principal.longitud=-365432; > RegHco[0].Principal.velocidad=60; > RegHco[0].Principal.ignicion=1; > RegHco[0].Principal.movimiento=0; > RegHco[0].Principal.distancia=100; > RegHco[0].Incremental[0].incTiempo=1000; > RegHco[0].Incremental[0].seD=0; > RegHco[0].Incremental[0].numSat=10; > RegHco[0].Incremental[0].edadP=1; > RegHco[0].Incremental[0].incLatitud=-1000; > RegHco[0].Incremental[0].incLongitud=1000; > RegHco[0].Incremental[0].velocidad=62; > RegHco[0].Incremental[0].ignicion=0; > RegHco[0].Incremental[0].movimiento=1; > RegHco[0].Incremental[0].incDistancia=1000; > > RegGuardar=new struct sRegHco[1]; > > //RegGuardar[0]=RegHco[0]; > /* RegGuardar[0].Principal.total=RegHco[0].Principal.total; > RegGuardar[0].Principal.ano=RegHco[0].Principal.ano; > RegGuardar[0].Principal.tiempo=RegHco[0].Principal.tiempo; > RegGuardar[0].Principal.seD=RegHco[0].Principal.seD; > RegGuardar[0].Principal.numSat=RegHco[0].Principal.numSat; > RegGuardar[0].Principal.edadP=RegHco[0].Principal.edadP; > RegGuardar[0].Principal.latitud=RegHco[0].Principal.latitud; > RegGuardar[0].Principal.longitud=RegHco[0].Principal.longitud; > RegGuardar[0].Principal.velocidad=RegHco[0].Principal.velocidad; > RegGuardar[0].Principal.ignicion=RegHco[0].Principal.ignicion; > RegGuardar[0].Principal.movimiento=RegHco[0].Principal.movimiento; > RegGuardar[0].Principal.distancia=RegHco[0].Principal.distancia; > RegGuardar[0].Incremental[0].incTiempo=RegHco[0].Incremental[0].incTiempo; > RegGuardar[0].Incremental[0].seD=RegHco[0].Incremental[0].seD; > RegGuardar[0].Incremental[0].numSat=RegHco[0].Incremental[0].numSat; > RegGuardar[0].Incremental[0].edadP=RegHco[0].Incremental[0].edadP; > RegGuardar[0].Incremental[0].incLatitud=RegHco[0].Incremental[0].incLatitud; > RegGuardar[0].Incremental[0].incLongitud=RegHco[0].Incremental[0].incLongitud; > RegGuardar[0].Incremental[0].velocidad=RegHco[0].Incremental[0].velocidad; > RegGuardar[0].Incremental[0].ignicion=RegHco[0].Incremental[0].ignicion; > RegGuardar[0].Incremental[0].movimiento=RegHco[0].Incremental[0].movimiento; > RegGuardar[0].Incremental[0].incDistancia=RegHco[0].Incremental[0].incDistancia;*/ > > copiarEstructura(RegHco[0],&RegGuardar[0]); > > fichero=fopen("pruebaBits.dat", "w+b"); > tamano=fwrite(RegGuardar,sizeof(*RegGuardar),1,fic hero), > fclose(fichero); > printf("El tamaño es: %d\n",tamano); > > delete(RegGuardar); > > fichero=fopen("pruebabits.dat","rb"); > tamano=fread(&Registro,sizeof(Registro),1,fichero) ; > fclose(fichero); > printf("El tamaño leído es: %d\n",tamano); > > printf("Total: %d\n",Registro.Principal.total); > printf("Año: %d\n",Registro.Principal.ano); > printf("Tiempo: %d\n",Registro.Principal.tiempo); > printf("Distancia: %d\n",Registro.Principal.distancia); > printf("Latitud y Longitud: %d, > %d\n",Registro.Principal.latitud,Registro.Principa l.longitud); > printf("incTiempo: %d\n",Registro.Incremental[0].incTiempo); > printf("incDistancia: %d\n",Registro.Incremental[0].incDistancia); > printf("incLatitud e incLongitud: %d, > %d\n",Registro.Incremental[0].incLatitud,Registro.Incremental[0].incLongitud); > > return 0; > } > > El archivo que se crea es el siguiente: > > 0000000: 029a cdcd 0300 0030 cdcd cdcd 479d 4000 .......0....G.***. > 0000010: 886c faff 7c64 0080 e803 d0cd 18fc cfcd .l..|d.......... > 0000020: e803 f8ce e803 cdcd 0000 00cd 0000 cccd ................ > 0000030: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000040: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000050: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000060: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000070: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000080: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000090: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000a0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000b0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000c0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000d0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000e0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000f0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000100: 0000 00cc 0000 cdcd 0d0a .......... > > Que, traducido a binario, si no me he equivocado, sería: > > 00000010100110101100110111001101000000110000000000 00000000110000110011011100110111001101110011010100 0111100111010100000000000000 > 10001000011011001111101011111111011111000110010000 00000010000000111010000000001111010000110011010001 1000111111001100111111001101 > 11101000000000111111100011001110111010000000001111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 001101110011010000110100001010 > > Sin embargo, para los valores que le doy, se supone que la primera > línea debería ser (igualmente, si no me he equivocado): > > 00000010001101000000000000000000011000000000011100 00000001000000100111010100011110000000000001011001 0011011110001111001000000000000000001100100 > > Cosa que no coincide. De ahí, mis dudas. Espero que podáis ayudarme. > > Un saludo y muchas gracias. > |
| |||
| Hola lestat_l: No he probado el programa porque no dispongo de mucho tiempo, pero yo diría que estás presuponiendo cómo debe ser la representación de la clase por parte de tu compilador y eso no es una postura correcta. La disposición en memoria de los atributos no está estipulada y dependerá de tu entorno, así como la representación en memoria de los valores de tales atributos depende del entorno de ejecución. Entiendo que estás presuponiendo que el compilador asigna el número especificado de bits por cada campo y luego pone uno tras otro. Yo creo que no es así, sino que por cuestión de la arquitectura de tu máquina, asigna en bloques de byte. Con lo que si tu tienes un campo del tipo: campo1:8 Te ocupa 8 bits Pero si tienes un campo del tipo: campo2:7 Te ocupa también 8 bits Y si tienes un campo del tipo: campo3:20 Te ocupa 24 bits Por lo que veo en el resultado, los valores parecen ajustados a la derecha en tal representación. Otra pregunta sería: ¿que hace con los bits sobrantes? A mi me parece que su valor es indefinido (lo que hubiera en memoria en el momento de la asignación). Creo que es basura y que simplemente no lo trata (descarta esos bits sobrantes). La razón de que sean múltiplos de 8 en tu plataforma, o de 16, 32, 64 (en otras), es cuestión de eficiencia, porque de lo contrario, por cada operación de asignación que hicieras, tendría que hacer el ordenador lo que tu no haces (aplicar máscaras, etc...), y es mucho más rápido, almacenarlo en bloques de tamaño que maneje el ordenador. Un saludo. Espero que te haya sido de ayuda lestat_l wrote: > Hola a todos: > > Tengo un pequeño problema con campos de bit. El caso es que necesito > que en un archivo se guarden datos con un número específico de bits, > y para ello pensé utilizar los campos de bit, que me parecieron una > alternativa más lógica que hacer desplazamientos y máscaras para > conseguir poner los valores adecuados. > > Definí la estructura, e hice la prueba con algunos valores. Así, los > escribe en un archivo, luego lee del archivo, y me los muestra en > pantalla. Perfecto. > > Sin embargo, y dado que luego ese archivo tendrá que tratarlo otra > aplicación, me puse a curiosear en el archivo que se había creado. El > resultado fue que no coincidía con lo que tendría que ser, con lo que > me surgen varias dudas: > > - ¿Cómo se almacenan estos campos de bit realmente? > - ¿Por qué, si inicializo los campos a 0, no guarda ceros en el > archivo, en las posiciones donde no he escrito otra cosa? > > El código es el siguiente: > > bits.h: > > #ifndef _BITS_ > #define _BITS_ > > typedef struct sPrincipal{ > unsigned int total:8; > unsigned int ano:7; > unsigned int tiempo:20; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int latitud:32; > signed int longitud:32; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int distancia:23; > } tipoPrincipal; > > typedef struct sIncremental{ > unsigned int incTiempo:11; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int incLatitud:18; > signed int incLongitud:18; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int incDistancia:16; > } tipoIncremental; > > typedef struct sRegHco{ > tipoPrincipal Principal; > tipoIncremental Incremental[15]; > } tipoRegHco; > > void copiarEstructura(tipoRegHco,tipoRegHco *); > void inicializarEstructura(tipoRegHco *); > > #endif > > bits.cpp: > > #include "bits.h" > > void copiarEstructura(tipoRegHco reg1,tipoRegHco *reg2){ > (*reg2).Principal.total=reg1.Principal.total; > (*reg2).Principal.ano=reg1.Principal.ano; > (*reg2).Principal.tiempo=reg1.Principal.tiempo; > (*reg2).Principal.seD=reg1.Principal.seD; > (*reg2).Principal.numSat=reg1.Principal.numSat; > (*reg2).Principal.edadP=reg1.Principal.edadP; > (*reg2).Principal.latitud=reg1.Principal.latitud; > (*reg2).Principal.longitud=reg1.Principal.longitud ; > (*reg2).Principal.velocidad=reg1.Principal.velocid ad; > (*reg2).Principal.ignicion=reg1.Principal.ignicion ; > (*reg2).Principal.movimiento=reg1.Principal.movimi ento; > (*reg2).Principal.distancia=reg1.Principal.distanc ia; > > for(short i=0;i<15;i++){ > (*reg2).Incremental[i].incTiempo=reg1.Incremental[i].incTiempo; > (*reg2).Incremental[i].seD=reg1.Incremental[i].seD; > (*reg2).Incremental[i].numSat=reg1.Incremental[i].numSat; > (*reg2).Incremental[i].edadP=reg1.Incremental[i].edadP; > (*reg2).Incremental[i].incLatitud=reg1.Incremental[i].incLatitud; > (*reg2).Incremental[i].incLongitud=reg1.Incremental[i].incLongitud; > (*reg2).Incremental[i].velocidad=reg1.Incremental[i].velocidad; > (*reg2).Incremental[i].ignicion=reg1.Incremental[i].ignicion; > (*reg2).Incremental[i].movimiento=reg1.Incremental[i].movimiento; > (*reg2).Incremental[i].incDistancia=reg1.Incremental[i].incDistancia; > } > } > > void inicializarEstructura(tipoRegHco *reg){ > (*reg).Principal.total=0; > (*reg).Principal.ano=0; > (*reg).Principal.tiempo=0; > (*reg).Principal.seD=0; > (*reg).Principal.numSat=0; > (*reg).Principal.edadP=0; > (*reg).Principal.latitud=0; > (*reg).Principal.longitud=0; > (*reg).Principal.velocidad=0; > (*reg).Principal.ignicion=0; > (*reg).Principal.movimiento=0; > (*reg).Principal.distancia=0; > > for(short i=0;i<15;i++){ > (*reg).Incremental[i].incTiempo=0; > (*reg).Incremental[i].seD=0; > (*reg).Incremental[i].numSat=0; > (*reg).Incremental[i].edadP=0; > (*reg).Incremental[i].incLatitud=0; > (*reg).Incremental[i].incLongitud=0; > (*reg).Incremental[i].velocidad=0; > (*reg).Incremental[i].ignicion=0; > (*reg).Incremental[i].movimiento=0; > (*reg).Incremental[i].incDistancia=0; > } > } > > pruebaBits.cpp: > > #include <stdio.h> > #include <stdlib.h> > #include "bits.h" > > FILE *fichero; > size_t tamano; > tipoRegHco Registro; > tipoRegHco *RegGuardar=NULL; > tipoRegHco RegHco[744]; > > int main(int argc, char* argv[]) > { > for(int i=0;i<744;i++){ > inicializarEstructura(&RegHco[i]); > } > > RegHco[0].Principal.total=2; > RegHco[0].Principal.ano=26; > RegHco[0].Principal.tiempo=3; > RegHco[0].Principal.seD=0; > RegHco[0].Principal.numSat=3; > RegHco[0].Principal.edadP=1; > RegHco[0].Principal.latitud=4234567; > RegHco[0].Principal.longitud=-365432; > RegHco[0].Principal.velocidad=60; > RegHco[0].Principal.ignicion=1; > RegHco[0].Principal.movimiento=0; > RegHco[0].Principal.distancia=100; > RegHco[0].Incremental[0].incTiempo=1000; > RegHco[0].Incremental[0].seD=0; > RegHco[0].Incremental[0].numSat=10; > RegHco[0].Incremental[0].edadP=1; > RegHco[0].Incremental[0].incLatitud=-1000; > RegHco[0].Incremental[0].incLongitud=1000; > RegHco[0].Incremental[0].velocidad=62; > RegHco[0].Incremental[0].ignicion=0; > RegHco[0].Incremental[0].movimiento=1; > RegHco[0].Incremental[0].incDistancia=1000; > > RegGuardar=new struct sRegHco[1]; > > //RegGuardar[0]=RegHco[0]; > /* RegGuardar[0].Principal.total=RegHco[0].Principal.total; > RegGuardar[0].Principal.ano=RegHco[0].Principal.ano; > RegGuardar[0].Principal.tiempo=RegHco[0].Principal.tiempo; > RegGuardar[0].Principal.seD=RegHco[0].Principal.seD; > RegGuardar[0].Principal.numSat=RegHco[0].Principal.numSat; > RegGuardar[0].Principal.edadP=RegHco[0].Principal.edadP; > RegGuardar[0].Principal.latitud=RegHco[0].Principal.latitud; > RegGuardar[0].Principal.longitud=RegHco[0].Principal.longitud; > RegGuardar[0].Principal.velocidad=RegHco[0].Principal.velocidad; > RegGuardar[0].Principal.ignicion=RegHco[0].Principal.ignicion; > RegGuardar[0].Principal.movimiento=RegHco[0].Principal.movimiento; > RegGuardar[0].Principal.distancia=RegHco[0].Principal.distancia; > RegGuardar[0].Incremental[0].incTiempo=RegHco[0].Incremental[0].incTiempo; > RegGuardar[0].Incremental[0].seD=RegHco[0].Incremental[0].seD; > RegGuardar[0].Incremental[0].numSat=RegHco[0].Incremental[0].numSat; > RegGuardar[0].Incremental[0].edadP=RegHco[0].Incremental[0].edadP; > RegGuardar[0].Incremental[0].incLatitud=RegHco[0].Incremental[0].incLatitud; > RegGuardar[0].Incremental[0].incLongitud=RegHco[0].Incremental[0].incLongitud; > RegGuardar[0].Incremental[0].velocidad=RegHco[0].Incremental[0].velocidad; > RegGuardar[0].Incremental[0].ignicion=RegHco[0].Incremental[0].ignicion; > RegGuardar[0].Incremental[0].movimiento=RegHco[0].Incremental[0].movimiento; > RegGuardar[0].Incremental[0].incDistancia=RegHco[0].Incremental[0].incDistancia;*/ > > copiarEstructura(RegHco[0],&RegGuardar[0]); > > fichero=fopen("pruebaBits.dat", "w+b"); > tamano=fwrite(RegGuardar,sizeof(*RegGuardar),1,fic hero), > fclose(fichero); > printf("El tamaño es: %d\n",tamano); > > delete(RegGuardar); > > fichero=fopen("pruebabits.dat","rb"); > tamano=fread(&Registro,sizeof(Registro),1,fichero) ; > fclose(fichero); > printf("El tamaño leído es: %d\n",tamano); > > printf("Total: %d\n",Registro.Principal.total); > printf("Año: %d\n",Registro.Principal.ano); > printf("Tiempo: %d\n",Registro.Principal.tiempo); > printf("Distancia: %d\n",Registro.Principal.distancia); > printf("Latitud y Longitud: %d, > %d\n",Registro.Principal.latitud,Registro.Principa l.longitud); > printf("incTiempo: %d\n",Registro.Incremental[0].incTiempo); > printf("incDistancia: %d\n",Registro.Incremental[0].incDistancia); > printf("incLatitud e incLongitud: %d, > %d\n",Registro.Incremental[0].incLatitud,Registro.Incremental[0].incLongitud); > > return 0; > } > > El archivo que se crea es el siguiente: > > 0000000: 029a cdcd 0300 0030 cdcd cdcd 479d 4000 .......0....G.***. > 0000010: 886c faff 7c64 0080 e803 d0cd 18fc cfcd .l..|d.......... > 0000020: e803 f8ce e803 cdcd 0000 00cd 0000 cccd ................ > 0000030: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000040: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000050: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000060: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000070: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000080: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000090: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000a0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000b0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000c0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000d0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000e0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000f0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000100: 0000 00cc 0000 cdcd 0d0a .......... > > Que, traducido a binario, si no me he equivocado, sería: > > 00000010100110101100110111001101000000110000000000 00000000110000110011011100110111001101110011010100 0111100111010100000000000000 > 10001000011011001111101011111111011111000110010000 00000010000000111010000000001111010000110011010001 1000111111001100111111001101 > 11101000000000111111100011001110111010000000001111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 001101110011010000110100001010 > > Sin embargo, para los valores que le doy, se supone que la primera > línea debería ser (igualmente, si no me he equivocado): > > 00000010001101000000000000000000011000000000011100 00000001000000100111010100011110000000000001011001 0011011110001111001000000000000000001100100 > > Cosa que no coincide. De ahí, mis dudas. Espero que podáis ayudarme. > > Un saludo y muchas gracias. > |
| |||
| Hola lestat_l: No he probado el programa porque no dispongo de mucho tiempo, pero yo diría que estás presuponiendo cómo debe ser la representación de la clase por parte de tu compilador y eso no es una postura correcta. La disposición en memoria de los atributos no está estipulada y dependerá de tu entorno, así como la representación en memoria de los valores de tales atributos depende del entorno de ejecución. Entiendo que estás presuponiendo que el compilador asigna el número especificado de bits por cada campo y luego pone uno tras otro. Yo creo que no es así, sino que por cuestión de la arquitectura de tu máquina, asigna en bloques de byte. Con lo que si tu tienes un campo del tipo: campo1:8 Te ocupa 8 bits Pero si tienes un campo del tipo: campo2:7 Te ocupa también 8 bits Y si tienes un campo del tipo: campo3:20 Te ocupa 24 bits Por lo que veo en el resultado, los valores parecen ajustados a la derecha en tal representación. Otra pregunta sería: ¿que hace con los bits sobrantes? A mi me parece que su valor es indefinido (lo que hubiera en memoria en el momento de la asignación). Creo que es basura y que simplemente no lo trata (descarta esos bits sobrantes). La razón de que sean múltiplos de 8 en tu plataforma, o de 16, 32, 64 (en otras), es cuestión de eficiencia, porque de lo contrario, por cada operación de asignación que hicieras, tendría que hacer el ordenador lo que tu no haces (aplicar máscaras, etc...), y es mucho más rápido, almacenarlo en bloques de tamaño que maneje el ordenador. Un saludo. Espero que te haya sido de ayuda lestat_l wrote: > Hola a todos: > > Tengo un pequeño problema con campos de bit. El caso es que necesito > que en un archivo se guarden datos con un número específico de bits, > y para ello pensé utilizar los campos de bit, que me parecieron una > alternativa más lógica que hacer desplazamientos y máscaras para > conseguir poner los valores adecuados. > > Definí la estructura, e hice la prueba con algunos valores. Así, los > escribe en un archivo, luego lee del archivo, y me los muestra en > pantalla. Perfecto. > > Sin embargo, y dado que luego ese archivo tendrá que tratarlo otra > aplicación, me puse a curiosear en el archivo que se había creado. El > resultado fue que no coincidía con lo que tendría que ser, con lo que > me surgen varias dudas: > > - ¿Cómo se almacenan estos campos de bit realmente? > - ¿Por qué, si inicializo los campos a 0, no guarda ceros en el > archivo, en las posiciones donde no he escrito otra cosa? > > El código es el siguiente: > > bits.h: > > #ifndef _BITS_ > #define _BITS_ > > typedef struct sPrincipal{ > unsigned int total:8; > unsigned int ano:7; > unsigned int tiempo:20; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int latitud:32; > signed int longitud:32; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int distancia:23; > } tipoPrincipal; > > typedef struct sIncremental{ > unsigned int incTiempo:11; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int incLatitud:18; > signed int incLongitud:18; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int incDistancia:16; > } tipoIncremental; > > typedef struct sRegHco{ > tipoPrincipal Principal; > tipoIncremental Incremental[15]; > } tipoRegHco; > > void copiarEstructura(tipoRegHco,tipoRegHco *); > void inicializarEstructura(tipoRegHco *); > > #endif > > bits.cpp: > > #include "bits.h" > > void copiarEstructura(tipoRegHco reg1,tipoRegHco *reg2){ > (*reg2).Principal.total=reg1.Principal.total; > (*reg2).Principal.ano=reg1.Principal.ano; > (*reg2).Principal.tiempo=reg1.Principal.tiempo; > (*reg2).Principal.seD=reg1.Principal.seD; > (*reg2).Principal.numSat=reg1.Principal.numSat; > (*reg2).Principal.edadP=reg1.Principal.edadP; > (*reg2).Principal.latitud=reg1.Principal.latitud; > (*reg2).Principal.longitud=reg1.Principal.longitud ; > (*reg2).Principal.velocidad=reg1.Principal.velocid ad; > (*reg2).Principal.ignicion=reg1.Principal.ignicion ; > (*reg2).Principal.movimiento=reg1.Principal.movimi ento; > (*reg2).Principal.distancia=reg1.Principal.distanc ia; > > for(short i=0;i<15;i++){ > (*reg2).Incremental[i].incTiempo=reg1.Incremental[i].incTiempo; > (*reg2).Incremental[i].seD=reg1.Incremental[i].seD; > (*reg2).Incremental[i].numSat=reg1.Incremental[i].numSat; > (*reg2).Incremental[i].edadP=reg1.Incremental[i].edadP; > (*reg2).Incremental[i].incLatitud=reg1.Incremental[i].incLatitud; > (*reg2).Incremental[i].incLongitud=reg1.Incremental[i].incLongitud; > (*reg2).Incremental[i].velocidad=reg1.Incremental[i].velocidad; > (*reg2).Incremental[i].ignicion=reg1.Incremental[i].ignicion; > (*reg2).Incremental[i].movimiento=reg1.Incremental[i].movimiento; > (*reg2).Incremental[i].incDistancia=reg1.Incremental[i].incDistancia; > } > } > > void inicializarEstructura(tipoRegHco *reg){ > (*reg).Principal.total=0; > (*reg).Principal.ano=0; > (*reg).Principal.tiempo=0; > (*reg).Principal.seD=0; > (*reg).Principal.numSat=0; > (*reg).Principal.edadP=0; > (*reg).Principal.latitud=0; > (*reg).Principal.longitud=0; > (*reg).Principal.velocidad=0; > (*reg).Principal.ignicion=0; > (*reg).Principal.movimiento=0; > (*reg).Principal.distancia=0; > > for(short i=0;i<15;i++){ > (*reg).Incremental[i].incTiempo=0; > (*reg).Incremental[i].seD=0; > (*reg).Incremental[i].numSat=0; > (*reg).Incremental[i].edadP=0; > (*reg).Incremental[i].incLatitud=0; > (*reg).Incremental[i].incLongitud=0; > (*reg).Incremental[i].velocidad=0; > (*reg).Incremental[i].ignicion=0; > (*reg).Incremental[i].movimiento=0; > (*reg).Incremental[i].incDistancia=0; > } > } > > pruebaBits.cpp: > > #include <stdio.h> > #include <stdlib.h> > #include "bits.h" > > FILE *fichero; > size_t tamano; > tipoRegHco Registro; > tipoRegHco *RegGuardar=NULL; > tipoRegHco RegHco[744]; > > int main(int argc, char* argv[]) > { > for(int i=0;i<744;i++){ > inicializarEstructura(&RegHco[i]); > } > > RegHco[0].Principal.total=2; > RegHco[0].Principal.ano=26; > RegHco[0].Principal.tiempo=3; > RegHco[0].Principal.seD=0; > RegHco[0].Principal.numSat=3; > RegHco[0].Principal.edadP=1; > RegHco[0].Principal.latitud=4234567; > RegHco[0].Principal.longitud=-365432; > RegHco[0].Principal.velocidad=60; > RegHco[0].Principal.ignicion=1; > RegHco[0].Principal.movimiento=0; > RegHco[0].Principal.distancia=100; > RegHco[0].Incremental[0].incTiempo=1000; > RegHco[0].Incremental[0].seD=0; > RegHco[0].Incremental[0].numSat=10; > RegHco[0].Incremental[0].edadP=1; > RegHco[0].Incremental[0].incLatitud=-1000; > RegHco[0].Incremental[0].incLongitud=1000; > RegHco[0].Incremental[0].velocidad=62; > RegHco[0].Incremental[0].ignicion=0; > RegHco[0].Incremental[0].movimiento=1; > RegHco[0].Incremental[0].incDistancia=1000; > > RegGuardar=new struct sRegHco[1]; > > //RegGuardar[0]=RegHco[0]; > /* RegGuardar[0].Principal.total=RegHco[0].Principal.total; > RegGuardar[0].Principal.ano=RegHco[0].Principal.ano; > RegGuardar[0].Principal.tiempo=RegHco[0].Principal.tiempo; > RegGuardar[0].Principal.seD=RegHco[0].Principal.seD; > RegGuardar[0].Principal.numSat=RegHco[0].Principal.numSat; > RegGuardar[0].Principal.edadP=RegHco[0].Principal.edadP; > RegGuardar[0].Principal.latitud=RegHco[0].Principal.latitud; > RegGuardar[0].Principal.longitud=RegHco[0].Principal.longitud; > RegGuardar[0].Principal.velocidad=RegHco[0].Principal.velocidad; > RegGuardar[0].Principal.ignicion=RegHco[0].Principal.ignicion; > RegGuardar[0].Principal.movimiento=RegHco[0].Principal.movimiento; > RegGuardar[0].Principal.distancia=RegHco[0].Principal.distancia; > RegGuardar[0].Incremental[0].incTiempo=RegHco[0].Incremental[0].incTiempo; > RegGuardar[0].Incremental[0].seD=RegHco[0].Incremental[0].seD; > RegGuardar[0].Incremental[0].numSat=RegHco[0].Incremental[0].numSat; > RegGuardar[0].Incremental[0].edadP=RegHco[0].Incremental[0].edadP; > RegGuardar[0].Incremental[0].incLatitud=RegHco[0].Incremental[0].incLatitud; > RegGuardar[0].Incremental[0].incLongitud=RegHco[0].Incremental[0].incLongitud; > RegGuardar[0].Incremental[0].velocidad=RegHco[0].Incremental[0].velocidad; > RegGuardar[0].Incremental[0].ignicion=RegHco[0].Incremental[0].ignicion; > RegGuardar[0].Incremental[0].movimiento=RegHco[0].Incremental[0].movimiento; > RegGuardar[0].Incremental[0].incDistancia=RegHco[0].Incremental[0].incDistancia;*/ > > copiarEstructura(RegHco[0],&RegGuardar[0]); > > fichero=fopen("pruebaBits.dat", "w+b"); > tamano=fwrite(RegGuardar,sizeof(*RegGuardar),1,fic hero), > fclose(fichero); > printf("El tamaño es: %d\n",tamano); > > delete(RegGuardar); > > fichero=fopen("pruebabits.dat","rb"); > tamano=fread(&Registro,sizeof(Registro),1,fichero) ; > fclose(fichero); > printf("El tamaño leído es: %d\n",tamano); > > printf("Total: %d\n",Registro.Principal.total); > printf("Año: %d\n",Registro.Principal.ano); > printf("Tiempo: %d\n",Registro.Principal.tiempo); > printf("Distancia: %d\n",Registro.Principal.distancia); > printf("Latitud y Longitud: %d, > %d\n",Registro.Principal.latitud,Registro.Principa l.longitud); > printf("incTiempo: %d\n",Registro.Incremental[0].incTiempo); > printf("incDistancia: %d\n",Registro.Incremental[0].incDistancia); > printf("incLatitud e incLongitud: %d, > %d\n",Registro.Incremental[0].incLatitud,Registro.Incremental[0].incLongitud); > > return 0; > } > > El archivo que se crea es el siguiente: > > 0000000: 029a cdcd 0300 0030 cdcd cdcd 479d 4000 .......0....G.***. > 0000010: 886c faff 7c64 0080 e803 d0cd 18fc cfcd .l..|d.......... > 0000020: e803 f8ce e803 cdcd 0000 00cd 0000 cccd ................ > 0000030: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000040: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000050: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000060: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000070: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000080: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000090: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000a0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000b0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000c0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000d0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000e0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000f0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000100: 0000 00cc 0000 cdcd 0d0a .......... > > Que, traducido a binario, si no me he equivocado, sería: > > 00000010100110101100110111001101000000110000000000 00000000110000110011011100110111001101110011010100 0111100111010100000000000000 > 10001000011011001111101011111111011111000110010000 00000010000000111010000000001111010000110011010001 1000111111001100111111001101 > 11101000000000111111100011001110111010000000001111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 001101110011010000110100001010 > > Sin embargo, para los valores que le doy, se supone que la primera > línea debería ser (igualmente, si no me he equivocado): > > 00000010001101000000000000000000011000000000011100 00000001000000100111010100011110000000000001011001 0011011110001111001000000000000000001100100 > > Cosa que no coincide. De ahí, mis dudas. Espero que podáis ayudarme. > > Un saludo y muchas gracias. > |
| |||
| Hola lestat_l: No he probado el programa porque no dispongo de mucho tiempo, pero yo diría que estás presuponiendo cómo debe ser la representación de la clase por parte de tu compilador y eso no es una postura correcta. La disposición en memoria de los atributos no está estipulada y dependerá de tu entorno, así como la representación en memoria de los valores de tales atributos depende del entorno de ejecución. Entiendo que estás presuponiendo que el compilador asigna el número especificado de bits por cada campo y luego pone uno tras otro. Yo creo que no es así, sino que por cuestión de la arquitectura de tu máquina, asigna en bloques de byte. Con lo que si tu tienes un campo del tipo: campo1:8 Te ocupa 8 bits Pero si tienes un campo del tipo: campo2:7 Te ocupa también 8 bits Y si tienes un campo del tipo: campo3:20 Te ocupa 24 bits Por lo que veo en el resultado, los valores parecen ajustados a la derecha en tal representación. Otra pregunta sería: ¿que hace con los bits sobrantes? A mi me parece que su valor es indefinido (lo que hubiera en memoria en el momento de la asignación). Creo que es basura y que simplemente no lo trata (descarta esos bits sobrantes). La razón de que sean múltiplos de 8 en tu plataforma, o de 16, 32, 64 (en otras), es cuestión de eficiencia, porque de lo contrario, por cada operación de asignación que hicieras, tendría que hacer el ordenador lo que tu no haces (aplicar máscaras, etc...), y es mucho más rápido, almacenarlo en bloques de tamaño que maneje el ordenador. Un saludo. Espero que te haya sido de ayuda lestat_l wrote: > Hola a todos: > > Tengo un pequeño problema con campos de bit. El caso es que necesito > que en un archivo se guarden datos con un número específico de bits, > y para ello pensé utilizar los campos de bit, que me parecieron una > alternativa más lógica que hacer desplazamientos y máscaras para > conseguir poner los valores adecuados. > > Definí la estructura, e hice la prueba con algunos valores. Así, los > escribe en un archivo, luego lee del archivo, y me los muestra en > pantalla. Perfecto. > > Sin embargo, y dado que luego ese archivo tendrá que tratarlo otra > aplicación, me puse a curiosear en el archivo que se había creado. El > resultado fue que no coincidía con lo que tendría que ser, con lo que > me surgen varias dudas: > > - ¿Cómo se almacenan estos campos de bit realmente? > - ¿Por qué, si inicializo los campos a 0, no guarda ceros en el > archivo, en las posiciones donde no he escrito otra cosa? > > El código es el siguiente: > > bits.h: > > #ifndef _BITS_ > #define _BITS_ > > typedef struct sPrincipal{ > unsigned int total:8; > unsigned int ano:7; > unsigned int tiempo:20; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int latitud:32; > signed int longitud:32; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int distancia:23; > } tipoPrincipal; > > typedef struct sIncremental{ > unsigned int incTiempo:11; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int incLatitud:18; > signed int incLongitud:18; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int incDistancia:16; > } tipoIncremental; > > typedef struct sRegHco{ > tipoPrincipal Principal; > tipoIncremental Incremental[15]; > } tipoRegHco; > > void copiarEstructura(tipoRegHco,tipoRegHco *); > void inicializarEstructura(tipoRegHco *); > > #endif > > bits.cpp: > > #include "bits.h" > > void copiarEstructura(tipoRegHco reg1,tipoRegHco *reg2){ > (*reg2).Principal.total=reg1.Principal.total; > (*reg2).Principal.ano=reg1.Principal.ano; > (*reg2).Principal.tiempo=reg1.Principal.tiempo; > (*reg2).Principal.seD=reg1.Principal.seD; > (*reg2).Principal.numSat=reg1.Principal.numSat; > (*reg2).Principal.edadP=reg1.Principal.edadP; > (*reg2).Principal.latitud=reg1.Principal.latitud; > (*reg2).Principal.longitud=reg1.Principal.longitud ; > (*reg2).Principal.velocidad=reg1.Principal.velocid ad; > (*reg2).Principal.ignicion=reg1.Principal.ignicion ; > (*reg2).Principal.movimiento=reg1.Principal.movimi ento; > (*reg2).Principal.distancia=reg1.Principal.distanc ia; > > for(short i=0;i<15;i++){ > (*reg2).Incremental[i].incTiempo=reg1.Incremental[i].incTiempo; > (*reg2).Incremental[i].seD=reg1.Incremental[i].seD; > (*reg2).Incremental[i].numSat=reg1.Incremental[i].numSat; > (*reg2).Incremental[i].edadP=reg1.Incremental[i].edadP; > (*reg2).Incremental[i].incLatitud=reg1.Incremental[i].incLatitud; > (*reg2).Incremental[i].incLongitud=reg1.Incremental[i].incLongitud; > (*reg2).Incremental[i].velocidad=reg1.Incremental[i].velocidad; > (*reg2).Incremental[i].ignicion=reg1.Incremental[i].ignicion; > (*reg2).Incremental[i].movimiento=reg1.Incremental[i].movimiento; > (*reg2).Incremental[i].incDistancia=reg1.Incremental[i].incDistancia; > } > } > > void inicializarEstructura(tipoRegHco *reg){ > (*reg).Principal.total=0; > (*reg).Principal.ano=0; > (*reg).Principal.tiempo=0; > (*reg).Principal.seD=0; > (*reg).Principal.numSat=0; > (*reg).Principal.edadP=0; > (*reg).Principal.latitud=0; > (*reg).Principal.longitud=0; > (*reg).Principal.velocidad=0; > (*reg).Principal.ignicion=0; > (*reg).Principal.movimiento=0; > (*reg).Principal.distancia=0; > > for(short i=0;i<15;i++){ > (*reg).Incremental[i].incTiempo=0; > (*reg).Incremental[i].seD=0; > (*reg).Incremental[i].numSat=0; > (*reg).Incremental[i].edadP=0; > (*reg).Incremental[i].incLatitud=0; > (*reg).Incremental[i].incLongitud=0; > (*reg).Incremental[i].velocidad=0; > (*reg).Incremental[i].ignicion=0; > (*reg).Incremental[i].movimiento=0; > (*reg).Incremental[i].incDistancia=0; > } > } > > pruebaBits.cpp: > > #include <stdio.h> > #include <stdlib.h> > #include "bits.h" > > FILE *fichero; > size_t tamano; > tipoRegHco Registro; > tipoRegHco *RegGuardar=NULL; > tipoRegHco RegHco[744]; > > int main(int argc, char* argv[]) > { > for(int i=0;i<744;i++){ > inicializarEstructura(&RegHco[i]); > } > > RegHco[0].Principal.total=2; > RegHco[0].Principal.ano=26; > RegHco[0].Principal.tiempo=3; > RegHco[0].Principal.seD=0; > RegHco[0].Principal.numSat=3; > RegHco[0].Principal.edadP=1; > RegHco[0].Principal.latitud=4234567; > RegHco[0].Principal.longitud=-365432; > RegHco[0].Principal.velocidad=60; > RegHco[0].Principal.ignicion=1; > RegHco[0].Principal.movimiento=0; > RegHco[0].Principal.distancia=100; > RegHco[0].Incremental[0].incTiempo=1000; > RegHco[0].Incremental[0].seD=0; > RegHco[0].Incremental[0].numSat=10; > RegHco[0].Incremental[0].edadP=1; > RegHco[0].Incremental[0].incLatitud=-1000; > RegHco[0].Incremental[0].incLongitud=1000; > RegHco[0].Incremental[0].velocidad=62; > RegHco[0].Incremental[0].ignicion=0; > RegHco[0].Incremental[0].movimiento=1; > RegHco[0].Incremental[0].incDistancia=1000; > > RegGuardar=new struct sRegHco[1]; > > //RegGuardar[0]=RegHco[0]; > /* RegGuardar[0].Principal.total=RegHco[0].Principal.total; > RegGuardar[0].Principal.ano=RegHco[0].Principal.ano; > RegGuardar[0].Principal.tiempo=RegHco[0].Principal.tiempo; > RegGuardar[0].Principal.seD=RegHco[0].Principal.seD; > RegGuardar[0].Principal.numSat=RegHco[0].Principal.numSat; > RegGuardar[0].Principal.edadP=RegHco[0].Principal.edadP; > RegGuardar[0].Principal.latitud=RegHco[0].Principal.latitud; > RegGuardar[0].Principal.longitud=RegHco[0].Principal.longitud; > RegGuardar[0].Principal.velocidad=RegHco[0].Principal.velocidad; > RegGuardar[0].Principal.ignicion=RegHco[0].Principal.ignicion; > RegGuardar[0].Principal.movimiento=RegHco[0].Principal.movimiento; > RegGuardar[0].Principal.distancia=RegHco[0].Principal.distancia; > RegGuardar[0].Incremental[0].incTiempo=RegHco[0].Incremental[0].incTiempo; > RegGuardar[0].Incremental[0].seD=RegHco[0].Incremental[0].seD; > RegGuardar[0].Incremental[0].numSat=RegHco[0].Incremental[0].numSat; > RegGuardar[0].Incremental[0].edadP=RegHco[0].Incremental[0].edadP; > RegGuardar[0].Incremental[0].incLatitud=RegHco[0].Incremental[0].incLatitud; > RegGuardar[0].Incremental[0].incLongitud=RegHco[0].Incremental[0].incLongitud; > RegGuardar[0].Incremental[0].velocidad=RegHco[0].Incremental[0].velocidad; > RegGuardar[0].Incremental[0].ignicion=RegHco[0].Incremental[0].ignicion; > RegGuardar[0].Incremental[0].movimiento=RegHco[0].Incremental[0].movimiento; > RegGuardar[0].Incremental[0].incDistancia=RegHco[0].Incremental[0].incDistancia;*/ > > copiarEstructura(RegHco[0],&RegGuardar[0]); > > fichero=fopen("pruebaBits.dat", "w+b"); > tamano=fwrite(RegGuardar,sizeof(*RegGuardar),1,fic hero), > fclose(fichero); > printf("El tamaño es: %d\n",tamano); > > delete(RegGuardar); > > fichero=fopen("pruebabits.dat","rb"); > tamano=fread(&Registro,sizeof(Registro),1,fichero) ; > fclose(fichero); > printf("El tamaño leído es: %d\n",tamano); > > printf("Total: %d\n",Registro.Principal.total); > printf("Año: %d\n",Registro.Principal.ano); > printf("Tiempo: %d\n",Registro.Principal.tiempo); > printf("Distancia: %d\n",Registro.Principal.distancia); > printf("Latitud y Longitud: %d, > %d\n",Registro.Principal.latitud,Registro.Principa l.longitud); > printf("incTiempo: %d\n",Registro.Incremental[0].incTiempo); > printf("incDistancia: %d\n",Registro.Incremental[0].incDistancia); > printf("incLatitud e incLongitud: %d, > %d\n",Registro.Incremental[0].incLatitud,Registro.Incremental[0].incLongitud); > > return 0; > } > > El archivo que se crea es el siguiente: > > 0000000: 029a cdcd 0300 0030 cdcd cdcd 479d 4000 .......0....G.***. > 0000010: 886c faff 7c64 0080 e803 d0cd 18fc cfcd .l..|d.......... > 0000020: e803 f8ce e803 cdcd 0000 00cd 0000 cccd ................ > 0000030: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000040: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000050: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000060: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000070: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000080: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000090: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000a0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000b0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000c0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000d0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000e0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000f0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000100: 0000 00cc 0000 cdcd 0d0a .......... > > Que, traducido a binario, si no me he equivocado, sería: > > 00000010100110101100110111001101000000110000000000 00000000110000110011011100110111001101110011010100 0111100111010100000000000000 > 10001000011011001111101011111111011111000110010000 00000010000000111010000000001111010000110011010001 1000111111001100111111001101 > 11101000000000111111100011001110111010000000001111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 001101110011010000110100001010 > > Sin embargo, para los valores que le doy, se supone que la primera > línea debería ser (igualmente, si no me he equivocado): > > 00000010001101000000000000000000011000000000011100 00000001000000100111010100011110000000000001011001 0011011110001111001000000000000000001100100 > > Cosa que no coincide. De ahí, mis dudas. Espero que podáis ayudarme. > > Un saludo y muchas gracias. > |
| |||
| Hola lestat_l: No he probado el programa porque no dispongo de mucho tiempo, pero yo diría que estás presuponiendo cómo debe ser la representación de la clase por parte de tu compilador y eso no es una postura correcta. La disposición en memoria de los atributos no está estipulada y dependerá de tu entorno, así como la representación en memoria de los valores de tales atributos depende del entorno de ejecución. Entiendo que estás presuponiendo que el compilador asigna el número especificado de bits por cada campo y luego pone uno tras otro. Yo creo que no es así, sino que por cuestión de la arquitectura de tu máquina, asigna en bloques de byte. Con lo que si tu tienes un campo del tipo: campo1:8 Te ocupa 8 bits Pero si tienes un campo del tipo: campo2:7 Te ocupa también 8 bits Y si tienes un campo del tipo: campo3:20 Te ocupa 24 bits Por lo que veo en el resultado, los valores parecen ajustados a la derecha en tal representación. Otra pregunta sería: ¿que hace con los bits sobrantes? A mi me parece que su valor es indefinido (lo que hubiera en memoria en el momento de la asignación). Creo que es basura y que simplemente no lo trata (descarta esos bits sobrantes). La razón de que sean múltiplos de 8 en tu plataforma, o de 16, 32, 64 (en otras), es cuestión de eficiencia, porque de lo contrario, por cada operación de asignación que hicieras, tendría que hacer el ordenador lo que tu no haces (aplicar máscaras, etc...), y es mucho más rápido, almacenarlo en bloques de tamaño que maneje el ordenador. Un saludo. Espero que te haya sido de ayuda lestat_l wrote: > Hola a todos: > > Tengo un pequeño problema con campos de bit. El caso es que necesito > que en un archivo se guarden datos con un número específico de bits, > y para ello pensé utilizar los campos de bit, que me parecieron una > alternativa más lógica que hacer desplazamientos y máscaras para > conseguir poner los valores adecuados. > > Definí la estructura, e hice la prueba con algunos valores. Así, los > escribe en un archivo, luego lee del archivo, y me los muestra en > pantalla. Perfecto. > > Sin embargo, y dado que luego ese archivo tendrá que tratarlo otra > aplicación, me puse a curiosear en el archivo que se había creado. El > resultado fue que no coincidía con lo que tendría que ser, con lo que > me surgen varias dudas: > > - ¿Cómo se almacenan estos campos de bit realmente? > - ¿Por qué, si inicializo los campos a 0, no guarda ceros en el > archivo, en las posiciones donde no he escrito otra cosa? > > El código es el siguiente: > > bits.h: > > #ifndef _BITS_ > #define _BITS_ > > typedef struct sPrincipal{ > unsigned int total:8; > unsigned int ano:7; > unsigned int tiempo:20; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int latitud:32; > signed int longitud:32; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int distancia:23; > } tipoPrincipal; > > typedef struct sIncremental{ > unsigned int incTiempo:11; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int incLatitud:18; > signed int incLongitud:18; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int incDistancia:16; > } tipoIncremental; > > typedef struct sRegHco{ > tipoPrincipal Principal; > tipoIncremental Incremental[15]; > } tipoRegHco; > > void copiarEstructura(tipoRegHco,tipoRegHco *); > void inicializarEstructura(tipoRegHco *); > > #endif > > bits.cpp: > > #include "bits.h" > > void copiarEstructura(tipoRegHco reg1,tipoRegHco *reg2){ > (*reg2).Principal.total=reg1.Principal.total; > (*reg2).Principal.ano=reg1.Principal.ano; > (*reg2).Principal.tiempo=reg1.Principal.tiempo; > (*reg2).Principal.seD=reg1.Principal.seD; > (*reg2).Principal.numSat=reg1.Principal.numSat; > (*reg2).Principal.edadP=reg1.Principal.edadP; > (*reg2).Principal.latitud=reg1.Principal.latitud; > (*reg2).Principal.longitud=reg1.Principal.longitud ; > (*reg2).Principal.velocidad=reg1.Principal.velocid ad; > (*reg2).Principal.ignicion=reg1.Principal.ignicion ; > (*reg2).Principal.movimiento=reg1.Principal.movimi ento; > (*reg2).Principal.distancia=reg1.Principal.distanc ia; > > for(short i=0;i<15;i++){ > (*reg2).Incremental[i].incTiempo=reg1.Incremental[i].incTiempo; > (*reg2).Incremental[i].seD=reg1.Incremental[i].seD; > (*reg2).Incremental[i].numSat=reg1.Incremental[i].numSat; > (*reg2).Incremental[i].edadP=reg1.Incremental[i].edadP; > (*reg2).Incremental[i].incLatitud=reg1.Incremental[i].incLatitud; > (*reg2).Incremental[i].incLongitud=reg1.Incremental[i].incLongitud; > (*reg2).Incremental[i].velocidad=reg1.Incremental[i].velocidad; > (*reg2).Incremental[i].ignicion=reg1.Incremental[i].ignicion; > (*reg2).Incremental[i].movimiento=reg1.Incremental[i].movimiento; > (*reg2).Incremental[i].incDistancia=reg1.Incremental[i].incDistancia; > } > } > > void inicializarEstructura(tipoRegHco *reg){ > (*reg).Principal.total=0; > (*reg).Principal.ano=0; > (*reg).Principal.tiempo=0; > (*reg).Principal.seD=0; > (*reg).Principal.numSat=0; > (*reg).Principal.edadP=0; > (*reg).Principal.latitud=0; > (*reg).Principal.longitud=0; > (*reg).Principal.velocidad=0; > (*reg).Principal.ignicion=0; > (*reg).Principal.movimiento=0; > (*reg).Principal.distancia=0; > > for(short i=0;i<15;i++){ > (*reg).Incremental[i].incTiempo=0; > (*reg).Incremental[i].seD=0; > (*reg).Incremental[i].numSat=0; > (*reg).Incremental[i].edadP=0; > (*reg).Incremental[i].incLatitud=0; > (*reg).Incremental[i].incLongitud=0; > (*reg).Incremental[i].velocidad=0; > (*reg).Incremental[i].ignicion=0; > (*reg).Incremental[i].movimiento=0; > (*reg).Incremental[i].incDistancia=0; > } > } > > pruebaBits.cpp: > > #include <stdio.h> > #include <stdlib.h> > #include "bits.h" > > FILE *fichero; > size_t tamano; > tipoRegHco Registro; > tipoRegHco *RegGuardar=NULL; > tipoRegHco RegHco[744]; > > int main(int argc, char* argv[]) > { > for(int i=0;i<744;i++){ > inicializarEstructura(&RegHco[i]); > } > > RegHco[0].Principal.total=2; > RegHco[0].Principal.ano=26; > RegHco[0].Principal.tiempo=3; > RegHco[0].Principal.seD=0; > RegHco[0].Principal.numSat=3; > RegHco[0].Principal.edadP=1; > RegHco[0].Principal.latitud=4234567; > RegHco[0].Principal.longitud=-365432; > RegHco[0].Principal.velocidad=60; > RegHco[0].Principal.ignicion=1; > RegHco[0].Principal.movimiento=0; > RegHco[0].Principal.distancia=100; > RegHco[0].Incremental[0].incTiempo=1000; > RegHco[0].Incremental[0].seD=0; > RegHco[0].Incremental[0].numSat=10; > RegHco[0].Incremental[0].edadP=1; > RegHco[0].Incremental[0].incLatitud=-1000; > RegHco[0].Incremental[0].incLongitud=1000; > RegHco[0].Incremental[0].velocidad=62; > RegHco[0].Incremental[0].ignicion=0; > RegHco[0].Incremental[0].movimiento=1; > RegHco[0].Incremental[0].incDistancia=1000; > > RegGuardar=new struct sRegHco[1]; > > //RegGuardar[0]=RegHco[0]; > /* RegGuardar[0].Principal.total=RegHco[0].Principal.total; > RegGuardar[0].Principal.ano=RegHco[0].Principal.ano; > RegGuardar[0].Principal.tiempo=RegHco[0].Principal.tiempo; > RegGuardar[0].Principal.seD=RegHco[0].Principal.seD; > RegGuardar[0].Principal.numSat=RegHco[0].Principal.numSat; > RegGuardar[0].Principal.edadP=RegHco[0].Principal.edadP; > RegGuardar[0].Principal.latitud=RegHco[0].Principal.latitud; > RegGuardar[0].Principal.longitud=RegHco[0].Principal.longitud; > RegGuardar[0].Principal.velocidad=RegHco[0].Principal.velocidad; > RegGuardar[0].Principal.ignicion=RegHco[0].Principal.ignicion; > RegGuardar[0].Principal.movimiento=RegHco[0].Principal.movimiento; > RegGuardar[0].Principal.distancia=RegHco[0].Principal.distancia; > RegGuardar[0].Incremental[0].incTiempo=RegHco[0].Incremental[0].incTiempo; > RegGuardar[0].Incremental[0].seD=RegHco[0].Incremental[0].seD; > RegGuardar[0].Incremental[0].numSat=RegHco[0].Incremental[0].numSat; > RegGuardar[0].Incremental[0].edadP=RegHco[0].Incremental[0].edadP; > RegGuardar[0].Incremental[0].incLatitud=RegHco[0].Incremental[0].incLatitud; > RegGuardar[0].Incremental[0].incLongitud=RegHco[0].Incremental[0].incLongitud; > RegGuardar[0].Incremental[0].velocidad=RegHco[0].Incremental[0].velocidad; > RegGuardar[0].Incremental[0].ignicion=RegHco[0].Incremental[0].ignicion; > RegGuardar[0].Incremental[0].movimiento=RegHco[0].Incremental[0].movimiento; > RegGuardar[0].Incremental[0].incDistancia=RegHco[0].Incremental[0].incDistancia;*/ > > copiarEstructura(RegHco[0],&RegGuardar[0]); > > fichero=fopen("pruebaBits.dat", "w+b"); > tamano=fwrite(RegGuardar,sizeof(*RegGuardar),1,fic hero), > fclose(fichero); > printf("El tamaño es: %d\n",tamano); > > delete(RegGuardar); > > fichero=fopen("pruebabits.dat","rb"); > tamano=fread(&Registro,sizeof(Registro),1,fichero) ; > fclose(fichero); > printf("El tamaño leído es: %d\n",tamano); > > printf("Total: %d\n",Registro.Principal.total); > printf("Año: %d\n",Registro.Principal.ano); > printf("Tiempo: %d\n",Registro.Principal.tiempo); > printf("Distancia: %d\n",Registro.Principal.distancia); > printf("Latitud y Longitud: %d, > %d\n",Registro.Principal.latitud,Registro.Principa l.longitud); > printf("incTiempo: %d\n",Registro.Incremental[0].incTiempo); > printf("incDistancia: %d\n",Registro.Incremental[0].incDistancia); > printf("incLatitud e incLongitud: %d, > %d\n",Registro.Incremental[0].incLatitud,Registro.Incremental[0].incLongitud); > > return 0; > } > > El archivo que se crea es el siguiente: > > 0000000: 029a cdcd 0300 0030 cdcd cdcd 479d 4000 .......0....G.***. > 0000010: 886c faff 7c64 0080 e803 d0cd 18fc cfcd .l..|d.......... > 0000020: e803 f8ce e803 cdcd 0000 00cd 0000 cccd ................ > 0000030: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000040: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000050: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000060: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000070: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000080: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000090: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000a0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000b0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000c0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000d0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000e0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 00000f0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................ > 0000100: 0000 00cc 0000 cdcd 0d0a .......... > > Que, traducido a binario, si no me he equivocado, sería: > > 00000010100110101100110111001101000000110000000000 00000000110000110011011100110111001101110011010100 0111100111010100000000000000 > 10001000011011001111101011111111011111000110010000 00000010000000111010000000001111010000110011010001 1000111111001100111111001101 > 11101000000000111111100011001110111010000000001111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 00110111001101110011011100110111001101110011011100 1101110011011100110111001101 > 11001101110011011100110111001101110011011100110111 001101110011010000110100001010 > > Sin embargo, para los valores que le doy, se supone que la primera > línea debería ser (igualmente, si no me he equivocado): > > 00000010001101000000000000000000011000000000011100 00000001000000100111010100011110000000000001011001 0011011110001111001000000000000000001100100 > > Cosa que no coincide. De ahí, mis dudas. Espero que podáis ayudarme. > > Un saludo y muchas gracias. > |
| |||
| Hola lestat_l: No he probado el programa porque no dispongo de mucho tiempo, pero yo diría que estás presuponiendo cómo debe ser la representación de la clase por parte de tu compilador y eso no es una postura correcta. La disposición en memoria de los atributos no está estipulada y dependerá de tu entorno, así como la representación en memoria de los valores de tales atributos depende del entorno de ejecución. Entiendo que estás presuponiendo que el compilador asigna el número especificado de bits por cada campo y luego pone uno tras otro. Yo creo que no es así, sino que por cuestión de la arquitectura de tu máquina, asigna en bloques de byte. Con lo que si tu tienes un campo del tipo: campo1:8 Te ocupa 8 bits Pero si tienes un campo del tipo: campo2:7 Te ocupa también 8 bits Y si tienes un campo del tipo: campo3:20 Te ocupa 24 bits Por lo que veo en el resultado, los valores parecen ajustados a la derecha en tal representación. Otra pregunta sería: ¿que hace con los bits sobrantes? A mi me parece que su valor es indefinido (lo que hubiera en memoria en el momento de la asignación). Creo que es basura y que simplemente no lo trata (descarta esos bits sobrantes). La razón de que sean múltiplos de 8 en tu plataforma, o de 16, 32, 64 (en otras), es cuestión de eficiencia, porque de lo contrario, por cada operación de asignación que hicieras, tendría que hacer el ordenador lo que tu no haces (aplicar máscaras, etc...), y es mucho más rápido, almacenarlo en bloques de tamaño que maneje el ordenador. Un saludo. Espero que te haya sido de ayuda lestat_l wrote: > Hola a todos: > > Tengo un pequeño problema con campos de bit. El caso es que necesito > que en un archivo se guarden datos con un número específico de bits, > y para ello pensé utilizar los campos de bit, que me parecieron una > alternativa más lógica que hacer desplazamientos y máscaras para > conseguir poner los valores adecuados. > > Definí la estructura, e hice la prueba con algunos valores. Así, los > escribe en un archivo, luego lee del archivo, y me los muestra en > pantalla. Perfecto. > > Sin embargo, y dado que luego ese archivo tendrá que tratarlo otra > aplicación, me puse a curiosear en el archivo que se había creado. El > resultado fue que no coincidía con lo que tendría que ser, con lo que > me surgen varias dudas: > > - ¿Cómo se almacenan estos campos de bit realmente? > - ¿Por qué, si inicializo los campos a 0, no guarda ceros en el > archivo, en las posiciones donde no he escrito otra cosa? > > El código es el siguiente: > > bits.h: > > #ifndef _BITS_ > #define _BITS_ > > typedef struct sPrincipal{ > unsigned int total:8; > unsigned int ano:7; > unsigned int tiempo:20; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int latitud:32; > signed int longitud:32; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int distancia:23; > } tipoPrincipal; > > typedef struct sIncremental{ > unsigned int incTiempo:11; > unsigned int seD:8; > unsigned int numSat:4; > unsigned int edadP:1; > signed int incLatitud:18; > signed int incLongitud:18; > unsigned int velocidad:6; > unsigned int ignicion:1; > unsigned int movimiento:1; > unsigned int incDistancia:16; > } tipoIncremental; > > typedef struct sRegHco{ > tipoPrincipal Principal; > tipoIncremental Incremental[15]; > } tipoRegHco; > > void copiarEstructura(tipoRegHco,tipoRegHco *); > void inicializarEstructura(tipoRegHco *); > > #endif > > bits.cpp: > > #include "bits.h" > > void copiarEstructura(tipoRegHco reg1,tipoRegHco *reg2){ > (*reg2).Principal.total=reg1.Principal.total; > (*reg2).Principal.ano=reg1.Principal.ano; > (*reg2).Principal.tiempo=reg1.Principal.tiempo; > (*reg2).Principal.seD=reg1.Principal.seD; > (*reg2).Principal.numSat=reg1.Principal.numSat; > (*reg2).Principal.edadP=reg1.Principal.edadP; > (*reg2).Principal.latitud=reg1.Principal.latitud; > (*reg2).Principal.longitud=reg1.Principal.longitud ; > (*reg2).Principal.velocidad=reg1.Principal.velocid ad; > (*reg2).Principal.ignicion=reg1.Principal.ignicion ; > (*reg2).Principal.movimiento=reg1.Principal.movimi ento; > (*reg2).Principal.distancia=reg1.Principal.distanc ia; > > for(short i=0;i<15;i++){ > (*reg2).Incremental[i].incTiempo=reg1.Incremental[i].incTiempo; > (*reg2).Incremental[i].seD=reg1.Incremental[i].seD; > (*reg2).Incremental[i].numSat=reg1.Incremental[i].numSat; > (*reg2).Incremental[i].edadP=reg1.Incremental[i].edadP; > (*reg2).Incremental[i].incLatitud=reg1.Incremental[i].incLatitud; > (*reg2).Incremental[i].incLongitud=reg1.Incremental[i].incLongitud; > (*reg2).Incremental[i].velocidad=reg1.Incremental[i].velocidad; > (*reg2).Incremental[i].ignicion=reg1.Incremental[i].ignicion; > (*reg2).Incremental[i].movimiento=reg1.Incremental[i].movimiento; > (*reg2).Incremental[i].incDistancia=reg1.Incremental[i].incDistancia; > } > } > > void inicializarEstructura(tipoRegHco *reg){ > (*reg).Principal.total=0; > (*reg).Principal.ano=0; > (*reg).Principal.tiempo=0; > (*reg).Principal.seD=0; > (*reg).Principal.numSat=0; > (*reg).Principal.edadP=0; |