Вопросы по С/С++ (СИ)
Re: Вопросы по С/С++ (СИ)
Подскажите, пожалуйста, как из массива uint16_t получить массив uint8_t. Наоборот знаю. Необходимо, чтобы значения переменных не были искажены.
Спасибо!
Спасибо!
- Реклама
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18561
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
интересно, как без искажений вы впихнете в uint8_t значение, например, 2096, которое легко помещается в uint16_t?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Мне надо разделить байты в 2 байтовом числе. Как это сделать?
Re: Вопросы по С/С++ (СИ)
Код: Выделить всё
low = input & 0x00FF;
high = (input >> 8) & 0x00FF;
подразумевается low, high - uint8, input uint16- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18561
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
задача поставлена слишком туманно, вариантов море:
ну и дальше в рамках фантазии аналогично...
Код: Выделить всё
// первый вариант: получаем массив байтов из массива int-ов
uint16_t source_array[SIZE]; // исходный массив
uint8_t *dest_array = (void*)source_array; // объявляем указатель на байт
uint8_t tmp = dest_array[10]; // извлекаем 11-й байт из исходного массива
// второй вариант: переделываем массив, оставляя только младшие байты из исходного массива
uint8_t dest_array[SIZE]; // объявляем результирующий массив
// в цикле заполняем массив
for(uint8_t i=0; i<SIZE; i++)
dest_array[i] = source_array[i];
// третий вариант - то же, что и второй, но берем старший байт
for(uint8_t i=0; i<SIZE; i++)
dest_array[i] = source_array[i] >> 8;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18561
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
избыточно, хватило бы и простоuldemir писал(а):или надо что-либо более адванснутое?Код: Выделить всё
low = input & 0x00FF; high = (input >> 8) & 0x00FF; подразумевается low, high - uint8, input uint16
Код: Выделить всё
low = input;
high = input >> 8;если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
перестраховался на случай, если вздумает 32-х битное подсунуть 
Re: Вопросы по С/С++ (СИ)
Огромное спасибо!
Re: Вопросы по С/С++ (СИ)
Помогите еще разок. Теперь есть массив из uint8_t первый байт младший, второй старший. Как наиболее эффективно сделать массив uitn16_t?
Спасибо!
Спасибо!
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Код: Выделить всё
typedef union {
uint8_t arr8[10];
uint16_t arr16[5];
} myType;
int main() {
myType x;
uint16_t a;
x.arr8[0] = 0x34;
x.arr8[1] = 0x57;
a = x.arr16[0]; // a присвоили значение 0x5734;
}- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18561
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель, я уже писал об этом:работать с таким указателем точно так же, как с массивом: dest - будет число из пары байт исходного массива. не ошибитесь только с индексацией - в новом массиве будет в 2 раза меньше элементов...
Код: Выделить всё
uint8_t source[SIZE]; // исходный массив байтов
uint16_t *dest = (void*)source; // новый массивесли рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Еще раз огромное спасибо!
Re: Вопросы по С/С++ (СИ)
Не не не. А как же выравнивание адресов? Некоторые архитектуры могут работать только с данными, выровненными по адресу, кратному размеру данных (или большей степени двойки). То есть, чтобы прочитать/записать в int16, это значение должно располагаться в памяти по адресу, кратному хотя бы двум, если нужно прочитать/записать int32, то оно должно располагаться по адресу, кратному хотя бы четырем, и так далее.ARV писал(а):самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель
Массив байтов может быть расположен по любому адресу. Приведя его указатель к указателю на массив двухбайтных значений можно нарушить требование выравнивания. Конечно, это не обязательно приведет к ошибке, возможно просто снизиться производительность, или даже ничего не случиться. Тем не менее такое решение довольно опасно и непереносимо.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18561
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
да да даmenzoda писал(а):Не не не.ARV писал(а):самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель
теория - это сила, но совать ее бесконтрольно в практику - только мешать
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Да и на 32-битных не приведет к ошибке, выравнивание, не выравнивание, это забота компилятора. Сказали второй байт, значит второй байт.
Re: Вопросы по С/С++ (СИ)
Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined. Так что все-равно нужно включать голову и писать переносимый код.ks0 писал(а):это забота компилятора. Сказали второй байт, значит второй байт.
А почему у меня программы не состоят на 90% из аппаратно-зависимых действий? Просто нужно минимизировать и отделять аппаратно-зависимый код от всего остального, и не плодить костыли да хаки там, где это не нужно. А это как раз тот случай, где их можно избежать.ARV писал(а):о какой переносимости может идти речь, если embedded-avr-программы на 90% состоят из аппаратно-зависимых (т.е. по определению непереносимых) действий?!
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18561
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
я не виноват, что вам не повезло...menzoda писал(а):А почему у меня программы не состоят на 90% из аппаратно-зависимых действий?
90% avr-овских проектов - это дрыгоножество и настройка периферии. если ваши проекты считают разложения Лагранжа - там будет 99% переносимого кода...
в сущности, спор бесполезен, истина где-то рядом...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Прикольно, представил себе почти все функции обработки строк char* оказываются undefined behavior!menzoda писал(а):Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined.
Re: Вопросы по С/С++ (СИ)
Че-то у меня лыжи не едут при попытки хранить строки во флеш. AVR GCC, пишу так
И вижу, что отладчик пишит, что во флеш по адресу 0х54 хранится число 0х60, которое есть указатель на адрес в ОЗУ, где и хранится сам текст, текст действительно там и оказывается. В буфер нефига вразумительного не копируется.
Че за фигня?! Т.е. во флеше только указатель, а сами данные в ОЗУ!
Код: Выделить всё
#include <avr/io.h>
#include <avr/pgmspace.h>
const char* s PROGMEM = "Text";
void main()
{
char c[20]; // буфер
strcpy_P(c,s);
}
Че за фигня?! Т.е. во флеше только указатель, а сами данные в ОЗУ!
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18561
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
прочтите о том, как правильно размещать строки во флеш при использовании старых версий AVR GCC. вы допустили ошибку - вы разместили во флеш указатель, е строка у вас окажется в ОЗУ. зачем вам флешевый указатель на ОЗУ? правильно так:
Однако, во множестве случаев может быть гораздо удобнее использование макроса PSTR:то есть можно задавать константные строки в таком виде, если более не потребуются адреса этих строк.
однако, в настоящее время WinAVR уже можно считать устаревшим компилятором, более свежие версии AVR GCC, а так же AVR Toolchain от Atmel уже поддерживают префикс __flash для определения констант в памяти программ, при этом работа с ними происходит прозрачно для большинства применений, т.е. уже не надо использовать функции с суффиксом _P или специальные средства типа pgm_read_byte
Код: Выделить всё
PROGMEM char str[] = "Что-то там";
sprcpy_P(s, str);Код: Выделить всё
strcpy_P(s, PSTR("Что-то там"));однако, в настоящее время WinAVR уже можно считать устаревшим компилятором, более свежие версии AVR GCC, а так же AVR Toolchain от Atmel уже поддерживают префикс __flash для определения констант в памяти программ, при этом работа с ними происходит прозрачно для большинства применений, т.е. уже не надо использовать функции с суффиксом _P или специальные средства типа pgm_read_byte
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!


