Что просят в задаче
Я не понимаю, что хотят от меня в данной задаче? Сама задача:
Составить и проверить в действии функцию, составляющую 32 - разрядное
беззнаковое целое значение uint32_t из четырех байт данных.
Обращаться со значением нужно при этом как с простым массивом из 4
элементов типа unsigned char.
При этом :
- Использовать указатели;
- Применить операции приведения типов данных;
- Заполненное 32 - разрядное значение должно быть возвращено из функции.
Как я вижу решение этой задачи:
#include <iostream>
using namespace std;
uint32_t to_uint32_t(unsigned char _1, unsigned char _2, unsigned char _3, unsigned char _4)
{
uint32_t result;
unsigned char value [] { _1, _2, _3, _4 };
result = 0xff & (static_cast<uint32_t>(_1));
result << 8;
result |= 0xff & (static_cast<uint32_t>(_2));
result << 16;
result |= 0xff & (static_cast<uint32_t>(_3));
result << 24;
result |= 0xff & (static_cast<uint32_t>(_4));
return result;
}
int main(int args_count, char** args)
{
cout << to_uint32_t('9', '2', '3','4');
return 0;
}
Ответы (3 шт):
Ну, можно и проще:
uint32_t to_uint32_t(uint32_t _1, uint32_t _2,
uint32_t _3, uint32_t _4)
{
return (_1 << 24) + (_2 << 16) + (_3 << 8) + _4;
}
int main(int args_count, char** args)
{
cout << hex << to_uint32_t('9', '2', '3','4') << endl;
}
Т.е. возложить преобразование байта в число прямо при вызове функции.
Только вы точно имели в виду передачу именно символов? Т.е. первый байт у вас именно 0x39, ну и так далее? А не 9?
Ах, да, преобразование обязательно использовать... Ну, тогда
uint32_t to_uint32_t(uint8_t _1, uint8_t _2,
uint8_t _3, uint8_t _4)
{
return
(static_cast<uint32_t>(_1) << 24) |
(static_cast<uint32_t>(_2) << 16) |
(static_cast<uint32_t>(_3) << 8) |
static_cast<uint32_t>(_4);
}
Но куда воткнуть указатели?... Разве что так (ох, как сейчас меня побьют любители strict aliasing...) -
uint32_t to_uint32_t(uint8_t _1, uint8_t _2,
uint8_t _3, uint8_t _4)
{
uint32_t r;
uint8_t * s = reinterpret_cast<uint8_t*>(&r);
*s++ = _4;
*s++ = _3;
*s++ = _2;
*s++ = _1;
return r;
}
Вопрос о порядке байтов в создаваемом числе оставляю открытым...
Насколько я понял, от вас хотят ровно этого
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
uint32_t
f (char c1, char c2, char c3, char c4)
{
uint32_t r;
unsigned char *t = (__typeof__(t))&r;
t[0] = c1; t[1] = c2; t[2] = c3; t[3] = c4;
return r;
}
int
main (int ac, char *av[])
{
uint32_t v = f('1', '2', '3', '4');
printf("0x%02x\n", v);
return puts("End") == EOF;
}
Транслируем и запускаем:
avp@avp-desktop:~/avp/hashcode$ g++ ttt.c -O3 && ./a.out
0x34333231
End
avp@avp-desktop:~/avp/hashcode$ echo $?
0
avp@avp-desktop:~/avp/hashcode$
Один из вариантов решения
#include <iostream>
#include <inttypes.h>
using namespace std;
uint32_t fill_bytes(unsigned char array[4])
{
uint32_t res;
void* p = static_cast<void*>(&res);
unsigned char* p_ar = static_cast<unsigned char*>(p);
for (int i = 0; i < 4; ++i)
p_ar[i] = array[i];
return res;
}
int main(int argc, char** args)
{
uint32_t v =1;
unsigned char ar[4] = {1,2,3,4};
cout << v << endl;
v = fill_bytes(ar);
cout << v << endl;
uint32_t mask = 0xFF;
for(int i = 0; i < 32; i += 8)
cout << ((v& (mask << i)) >> i) << endl;
return 0;
}