указатели и байтовые массивы в с ++ - PullRequest
0 голосов
/ 23 ноября 2011

Я новичок в указателях и хотел бы сделать такую ​​функцию, чтобы добавить каждый байт в памяти из переменной int в каждую ячейку в unsigned char.Пожалуйста, см. Код ниже

int main()
{ 
 unsigned char buffer[4] = {0};
 int number = 15
 unsigned char *ptBuffer = &buffer;

 return 0;
}

, поэтому вывод будет

buffer[0]= 0,
buffer[1]= 0,
buffer[2]= 0,
buffer[3]= F

, поэтому

number = 15 => 0x000F

Ответы [ 5 ]

3 голосов
/ 23 ноября 2011

Переносимое решение, которое не использует псевдонимы (что, вероятно, будет раздражать оптимизатор), заключается в использовании некоторых битовых операций, предоставляемых C ++. Если вы уверены, что целое число занимает 4 байта на вашем компьютере (но в производственном коде вы действительно не должны предполагать это, так как размер целого числа не определен), это будет выглядеть так:

int x = ...;

unsigned char bytes[4] = {
    (x >> 24) & 0xFF,
    (x >> 16) & 0xFF,
    (x >> 8)  & 0xFF,
    (x >> 0)  & 0xFF,
};

>> - битовые сдвиги вправо. & являются побитовыми и (1 и 0 = 0, 1 и 1 = 1, 0 и 1 = 0).

Затем вы выводите их, например. std::cout << (int)bytes[0] << ....

0 голосов
/ 24 ноября 2011

У меня есть ощущение, что я могу ошибаться, поскольку я предполагаю, что об этом уже упоминалось, если бы это работало, но это звучит как хорошее место для использования union.

union IntBytes
{
   int intVal;
   unsigned char byteVal[sizeof(int)];
};

IntBytes foo;
foo.intVal = 15;
// now access foo.byteVal[0], [1], etc.

Я думаю, что это должно быть законно, и я ожидаю, что оно достигнет желаемого результата.

0 голосов
/ 23 ноября 2011

Ваш вопрос немного неясен, но, насколько я понимаю, вы хотели бы заполнить массив символов байтами, составляющими int.Обратите внимание, что результаты, которые вы получите, будут зависеть от платформы ... т. Е. На машине с прямым порядком байтов вы получите

buffer[0]= F, buffer[1]= 0, buffer[2]= 0, buffer[3]= 0.

. Для этого есть много способов, но я думаю, что в этом случае наиболее педагологическимибудет выглядеть следующим образом:

void read_int(unsigned char *results, int num) {
    int count = 0;
    char *num_bytes=(char*)&num;
    for (count=0; count<sizeof(int); count++) {
        results[count]=num_bytes[count];
    }
}
int main() {
    unsigned char buffer[4] = {0};
    int number = 15;

    read_int(buffer, number);
    return 0;
}

Обратите внимание, как вы можете привести указатель одного типа к указателю другого, и как вы можете использовать указатель как массив и массив как указатель.

0 голосов
/ 23 ноября 2011
unsigned char buffer[4] = {0};
int number = htonl(15);
unsigned char *ptBuffer = &buffer[0];
*(int*)ptBuffer = *(int*)&number;

даст вам буфер [0] = 0, буфер [1] = 0, буфер [2] = 0, буфер [3] = 15

Это также можно сделать с помощью этого кода:

int number = 15;
unsigned char buffer[4] = {0};
__asm mov eax, number
__asm bswap eax
__asm mov dword ptr buffer, eax

Тогда вы можете определить его так:

#define SWAP(val,buf) __asm mov eax, val \
                      __asm bswap eax \
                      __asm mov dword ptr buf, eax

и назвать его так:

int number = 15;
unsigned char buffer[4] = {0};
SWAP(number, buffer);
0 голосов
/ 23 ноября 2011

Хотя то, что вы делаете, кажется несколько бессмысленным и пахнет домашней работой, вот что вы можете сделать.

#include <iomanip>
#include <iostream>

int main(int argc, char* argv[])
{
    unsigned char buffer[sizeof(int)];
    int i, number=15;

    for (i=0; i < (int)sizeof(buffer); i++, number >>= 8) {
        buffer[sizeof(buffer)-i-1]=number&0xff;
    }

    for (i=0; i < (int)sizeof(buffer); i++) {
        std::cout << std::hex << std::setw(2)
                  << std::setfill('0')
                  << int(buffer[i]) << ' ';
    }
    std::cout << std::endl;

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