Qual a melhor maneira de alterar apenas um byte de uma variável long de 4 bytes ?
Exemplo. Como alterar o terceiro byte sem mexer nos demais ?
usar operações bit a bit
unsigned long v = 123456;
v |= 0bxxxxxxxx000000; // use x = 1 para forçar esses bits a 1, 0 para manter o bit inalterado
v &= 0byyyyyyyy11111111; // use y = 0 para forçar esses bits a 0, 1 para manter o bit inalterado
você também pode usar um ponteiro de byte para a variável, modificar a memória e, em seguida, memcpy() em uma variável para o resultado
unsigned long v = 123456;
unsigned long result;
unsigned long * ptr = &v;
ptr[2] = 0bxxxxxxxx; // modifique o terceiro byte (o índice começa em 0). lembre-se que o GCC usa little endian para representar os dados na memória
memcpy(&result, ptr, sizeof result); // https://cplusplus.com/reference/cstring/memcpy/
Interessante.
Em PicBasic seria operação muito simples:
V.byte[2] = novovalor.
No seu exemplo por mascaramento teria como fazer em hexadecimal ?
void setup() {
Serial.begin(115200);
unsigned long v = 0xDE00BEEF;
v |= 0x00AD0000;
Serial.print("v = 0x"); Serial.println(v, HEX);
}
void loop() {}
Isso modifica a variável mas nesse exemplo eu tenho de escreve-lo diretamente.
Eu preciso que o novo byte seja dinâmico, que eu possa manipulá-lo separadamente antes de inserir na variável - que ele possa ser representado por uma variável separada.
O exemplo com memcpy e com o ptr[2] não funcionou.
O ideal seria algo como bitWrite() mas que fosse com bytes e não bits
➜
uint32_t v = 0xDE00BEEF;
void setup() {
Serial.begin(115200);
uint8_t x = 0xAD;
// modificação direta de bytes
uint8_t * ptr = (uint8_t *) &v;
ptr[2] = x;
Serial.print("Result = 0x"); Serial.println(v, HEX);
// ou se você tivesse um buffer de bytes, deseja mover para o uin32_t
uint32_t r;
memcpy(&r, ptr, sizeof r);
Serial.print("Result = 0x"); Serial.println(r, HEX);
}
void loop() {}
Ok. Agora funcionou . Obrigado pelo help.
Já pensaste em uniões?
union LongBytes {
unsigned long ulong ;
unsigned char uchar[4];
} data;
data.ulong = 50; //escrever na variável ulong.
data.uchar[1] = 20; //escrever no segundo byte da variável.
É apenas mais uma maneira, não muito comum, de mexer com a memória.
não está correto em C++ se você tentar ler do outro elemento
It's undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.