a
é um ponteiro para uma matriz de bytes. Se você o converter em um uint16_t e atribuí-lo a b
, ele b
conterá o endereço da base da matriz (onde está armazenado) na SRAM. Se você deseja tratar os dois bytes da matriz a
como um número inteiro, use uma união como sugerido pelo usuário14284, mas lembre-se de que a união representará a matriz de bytes na ordem de bytes da arquitetura da arquitetura (no AVR, seria pouco -endian, que significa byte 0 é o byte menos significativo). A maneira de escrever isso no código é:
union{
uint8_t a[2];
uint16_t b;
} x;
x.b[0] = 0x35;
x.b[1] = 0x4A;
// by virtue of the above two assignments
x.a == 0x4A35 // is true
Outra maneira de fazer isso sem usar uma união é converter a
em um ponteiro uint16_t e desreferenciar da seguinte forma:
uint8_t a[2] = {0x35, 0x4A};
uint16_t b = *((uint16_t *) a);
b == 0x4A35; // because AVR is little endian
Se você estiver usando o buffer para armazenar grandes dados endian (por exemplo, ordem de bytes da rede), precisará trocar de bytes para usar qualquer uma dessas técnicas. Uma maneira de fazer isso sem ramificações ou variáveis temporárias é:
uint8_t a[2] = {0x35, 0x4A};
a[0] ^= a[1];
a[1] ^= a[0];
a[0] ^= a[1];
a[0] == 0x4A; // true
a[1] == 0x35; // true
Aliás, isso não é um AVR ou mesmo um problema incorporado. Nível de aplicativo de rede código escrito para PCs normalmente chamadas de funções chamadas htonl
, htons
(host para rede, de 32 e 16-bit variantes) e ntohl
, ntohs
(rede de host, de 32 e 16-bit variantes), cuja implementações são alvo dependente da arquitetura para saber se eles troque os bytes ou não (sob a suposição de que os bytes transmitidos 'on the wire' são sempre big-endian quando fazem parte de palavras de vários bytes).