Convertir matriz de bytes a entero

Tengo una matriz de 4 bytes (datos) de tipo uint8_t , que representa un entero de datos de velocidad. Estoy intentando convertir esta matriz en uint32_t entero uint32_t (velocidad), multiplicar esta velocidad por 10 y luego restaurarla de nuevo a la matriz de 4 bytes (datos). El formato de los datos está claro en el siguiente código. Siempre me sale el error:

“Asignación a expresión con tipo de matriz”

El código:

 volatile uint8_t data[4] = {0x00 , 0x00, 0x00, 0x00}; volatile uint32_t speed; speed=( uint32_t)*data; speed=speed*10; data=(uint8_t*)speed; 

Su código no funciona porque durante data=(uint8_t*)speed; no obtiene un “lvalue” para los datos, solo obtiene un tipo de matriz que no se puede utilizar en la asignación o cualquier forma de aritmética. De manera similar, speed=( uint32_t)*data; es un error porque solo te da el primer elemento de la matriz.

La única forma correcta de hacerlo es:

 volatile uint8_t data[4] = {0x00 , 0x00, 0x00, 0x00}; volatile uint32_t speed; speed = (uint32_t)data[0] << 24 | (uint32_t)data[1] << 16 | (uint32_t)data[2] << 8 | (uint32_t)data[3] << 0; speed=speed*10; data[0] = (uint8_t) ((speed >> 24) & 0xFFu); data[1] = (uint8_t) ((speed >> 16) & 0xFFu); data[2] = (uint8_t) ((speed >> 8) & 0xFFu); data[3] = (uint8_t) ((speed >> 0) & 0xFFu); 

Este es un código 100% portátil y bien definido. No se realizan promociones implícitas. Este código no se basa en endianess u otro comportamiento definido por la implementación. ¿Por qué escribir código que lo hace, cuando puedes escribir código que no lo hace?

Para estar seguro de acuerdo con la seguridad, portátil y seguro, debe recrear sus datos:

 speed = ((uint32_t)data[0]) << 24 | ((uint32_t)data[1]) << 16 | ((uint32_t)data[2]) << 8 | ((uint32_t)data[3]); 

o

 speed = ((uint32_t)data[3]) << 24 | ((uint32_t)data[2]) << 16 | ((uint32_t)data[1]) << 8 | ((uint32_t)data[0]); 

Elija la solución según la posición del byte más significativo.


Obtiene un error de "asignación a expresión con tipo de matriz" porque no puede asignar directamente una matriz: data=(uint8_t*)speed; está totalmente prohibido en C, definitivamente no puede tener una matriz para lvalue. Tienes que hacer la operación inversa:

 data[0] = (uint8_t)((speed >> 24) & 0x00FF); data[1] = (uint8_t)((speed >> 16) & 0x00FF); data[2] = (uint8_t)((speed >> 8) & 0x00FF); data[3] = (uint8_t)(speed & 0x00FF); 

o, según la posición del byte más significativo:

 data[3] = (uint8_t)((speed >> 24) & 0x00FF); data[2] = (uint8_t)((speed >> 16) & 0x00FF); data[1] = (uint8_t)((speed >> 8) & 0x00FF); data[0] = (uint8_t)(speed & 0x00FF); 

EDITAR

No use cast o memcpy como se menciona en los comentarios y la respuesta original: además de los problemas de no portabilidad, tendrá problemas de seguridad, restricciones de alineación y reglas de alias en algunas plataformas, el comstackdor puede generar código incorrecto, gracias al usuario694733 | Ver aquí - gracias a Lundin.

  speed = *((uint32_t *)data); // DANGEROUS NEVER USE IT *((uint32_t *)data) = speed; // DANGEROUS NEVER USE IT