Как изменить более 1 байта в массиве? - PullRequest
0 голосов
/ 21 февраля 2019

Что я пытаюсь:

BYTE test[] = {0x00,0x00,0x00,0x00};
*(test+1) = 0xFFFF;

Что я получаю:

00000000 11111111 00000000 00000000

Что я ожидаю или хочу достичь:

00000000 11111111 11111111 00000000

Справочная информация: Водна часть моей программы мне нужно вставить слово в часть массива.Да, обычно я мог бы просто сделать

*(test+1) = 0xFF;
*(test+2) = 0xFF;

, но мне интересно, есть ли возможность сделать это в виде одной строки, как в первом примере.Memcpy здесь не вариант, так как мне нужно было бы выделить место для второго массива.

Ответы [ 4 ]

0 голосов
/ 21 февраля 2019
#define modify(dest,src,pos)    do { unsigned char *tmp =(void *)&dest; memcpy(tmp + pos,&src, sizeof(src));}while(0)

void *modify1(void *dest, void *src, size_t pos, size_t len)
{
    unsigned char *tmp = dest;
    memcpy(tmp + pos, src, len);
    return tmp + pos;
}

примеры:

char x[10];
short y = 0xffff;
modify(x,y,3);

or modify1(x,&y, 3, sizeof(y));

Обратите внимание, что макрос один не будет работать при всех обстоятельствах.

0 голосов
/ 21 февраля 2019

Следующий код представляет собой общее решение, которое позволяет записать значение 2 байта (16 бит) в последовательные ячейки массива:

uint16 data = 0xFFFF;

BYTE test[] = {0x00,0x00,0x00,0x00};
*(test+1) = data & 0xFF;
*(test+2) = data >> 8;

Результат будет:

00000000 11111111 11111111 00000000

Так что просто измените значение data.

0 голосов
/ 21 февраля 2019

Доступны следующие варианты:

  1. test[1] = 0xFF;
    test[2] = 0xFF;
    
  2. memset(test + 1, 0xFF, 2);
    
  3. const char bytes[2] = {0xFF, 0xFF};
    memcpy(test + 1, bytes, 2);
    
  4. uint16_t value = 0xFFFF;     // beware of byte order
    memcpy(test + 1, &value, 2);
    
  5. memcpy(test + 1, (const unsigned char []){0xFF, 0xFF}, 2));
    
  6. или любой другой код, который адресует отдельные байты отдельно.


Что такое , а не вариантis:

*(uint16_t)&test[1] = 0xFFFF;

Причина проста: он нарушает два правила в C: строгое совмещение имен и .Хуже всего то, что вы можете обойтись этим в этой части кода, но разыменование невыровненных uint16_t указателей никогда не безопасно, даже на x86-64, который предположительноподдерживает не выровненный доступ

0 голосов
/ 21 февраля 2019

В этом случае memset(test+1, 0xFF, 2) должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...