Easyelectronics.ru • Просмотр темы - Как инкрементить данные в массиве на С

Easyelectronics.ru

Электроника для всех
Текущее время: 19 авг 2018, 21:52

Часовой пояс: UTC + 5 часов



    • JLCPCB - Прототипы 10 PCBs всего за 2$ (100*100mm, 2-layer)
    • Как мы делаем платы, смотрите на YouTube
    • Крупнейшая китайская фабрика прототипов. 300000+ заказчиков и 10000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин комплектующих.

Начать новую тему Ответить на тему  [ Сообщений: 36 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 01:31 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1674
Откуда: Харьков
Есть массив, допустим
Код:
uint8_t Arr[5] = {0,0,0,0,0};

Можно ли как-то (в за минимум движений) его инкрементить чтоб массив считался как одна переменная 40 бит?
Инкрементить каждое значение с проверкой на переполнение как бы и так понятно.

UPD: это все нужно на STM32 под Keil.


Последний раз редактировалось alexsam 01 апр 2018, 15:13, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 01:38 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
union? но там могут быть грабли в виде порядка байт...
Может, ещё, вставка на асме?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 01:47 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 4676
1. дополнить массив до 64 бит
2. сделать его на границе dword
3. через переопределение типов (указатель) обозвать массив как одно слово uint64_t.
4. юзать инкремент/декремент так, как считаете нужным.


Последний раз редактировалось u37 01 апр 2018, 01:48, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 01:48 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1674
Откуда: Харьков
h4lf писал(а):
union? но там могут быть грабли в виде порядка байт...

Так а как его инкрементить?
Я знаю только такое:
Код:
union Data {
   int a;
   int b;
};

union Data data;
data.a = 1;
data.b = 2;

??
h4lf писал(а):
Может, ещё, вставка на асме?

Да что угодно, но как?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 01:49 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1674
Откуда: Харьков
u37 писал(а):
1. дополнить массив до 64 бит
2. сделать его на границе dword
3. через переопределение типов (указатель) обозвать массив как одно слово uint64_t.
4. юзать инкремент/декремент так, как считаете нужным.

А если больше 64?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 01:52 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 4676
uint128_t. Неожиданно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 01:57 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1674
Откуда: Харьков
u37 писал(а):
uint128_t. Неожиданно.

Осталось только компилятор научить понимать.
Keil не могет


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 02:10 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
инкремент ++ же. Только инкрементить надо будет не сам массив, а uint64, который при помощи unit занимает ту же память что и массив. Но массив для этого нужно дополнить слева и позаботится о выравнивании, как уже написал u37. Но если остроконечный порядок байт...

На асме - взять адрес последнего элемента и... есть соответствующие команды сложения с учётом переноса, хоть 1032 бит можно инкрементить. Как делать асм вставки - надо смотреть конкретный компилятор. И где-то видел целые статьи про это.

Но это всё будет непереносимо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 02:34 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1674
Откуда: Харьков
Да, порядок байт все портит.
Вобщем лучше через переменную на 64 бита.
Асм еще покурю.
Спасибо


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 02:48 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
Вот через переменную на 64 бита острый конец всё и портит... ведь младший байт с правого края массива?
Изображение


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 13:21 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1674
Откуда: Харьков
Я имел ввиду вообще не использовать массив, а инкрементить только переменную


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 13:27 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
а так?
Код:
*((uint64_t *)Arr)++;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 15:06 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
jenya77, так просто не получится, точнее -- может получится, но далеко не всегда. Потому, что массив Arr, в данном случае, содержит пять элементов (пять отдельных байт, расположенных в памяти по порядку), а uint64_t содержит восемь байт и порядок их в памяти может быть различным (в общем случае). Даже если он подходящий (допустим, что порядок всех восьми байт тупоконечный -- от старшего к младшему, а элементы массива надо инкрементить справа-налево), то просто преобразовать Arr (это указатель на начало массива) в указатель на uint64_t можно, но инкремент будет происходить где-то вне массива, так как в нём всего пять байт. Ну и с выравниванием могут быть проблемы. Или я ошибаюсь в этих рассуждениях?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 15:16 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
h4lf писал(а):
jenya77, так просто не получится, точнее -- может получится, но далеко не всегда. Потому, что массив Arr, в данном случае, содержит пять элементов (пять отдельных байт, расположенных в памяти по порядку), а uint64_t содержит восемь байт и порядок их в памяти может быть различным (в общем случае). Даже если он подходящий (допустим, что порядок всех восьми байт тупоконечный -- от старшего к младшему, а элементы массива надо инкрементить справа-налево), то просто преобразовать Arr (это указатель на начало массива) в указатель на uint64_t можно, но инкремент будет происходить где-то вне массива, так как в нём всего пять байт. Ну и с выравниванием могут быть проблемы. Или я ошибаюсь в этих рассуждениях?

дополнить массив до 64
или так
Код:
int count;
count++;
if (count >= MAX_40BIT_VALUE)
    count = 0;

*((uint64_t *)Arr) = count;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 15:23 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2119
Вопрос в том, зачем че-то изобретать? Просто берите и инкрементируйте. Вообще же, Си позволяет работать через указатели. Любой массив, любую структуру можно представить в виде указателя на массив (структуру), то есть на первый элемент. Указатель - есть отдельная 4-байтовая переменная, содержащая численное значение адреса первого элемента массива (структуры). Операции по указателю равнозначны непосредственным операциям с массивом. В дополнение к этому вы можете изменить размерность доступа к массиву. Но вот что касается порядка байтов LE - это да, надо помнить.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 15:42 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
BusMaster писал(а):
Просто берите и инкрементируйте.
ну автор вроде бы избавился от массива и теперь просто инкрементирует. Но изначально-то нужно было "Можно ли как-то (в за минимум движений) его инкрементить чтоб массив считался как одна переменная 40 бит". Уж не знаю, зачем это было нужно, но если без этого можно обойтись, то лучше так и сделать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 17:04 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 475
alexsam писал(а):
Есть массив, допустим
Код:
uint8_t Arr[5] = {0,0,0,0,0};

Можно ли как-то (в за минимум движений) его инкрементить чтоб массив считался как одна переменная 40 бит?

Хорошая хохма, я даже почти повёлся.
union arangytang
{
struct
{
uint8_t Arr[5];
uint8_t free0;
uint8_t free1;
uint8_t free2;
};
struct
{
uint64_t Arr_raw :40;
uint64_t Arr_free:24;
};
uint64_t raw_t64;
};

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 18:10 
Старожил

Зарегистрирован: 07 фев 2011, 21:00
Сообщения: 446
Откуда: Ханты-Мансийск
если нельзя преобразовать массив в uint64_t, то
Show

Наверняка переменную sum, можно оптимизировать


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 18:26 
Старожил

Зарегистрирован: 07 фев 2011, 21:00
Сообщения: 446
Откуда: Ханты-Мансийск
или как-то так
Show


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 19:18 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 475
При работе через указатель переполнение учитывается через существующий тип переменной. Нельзя задать тип переменной указателя не кратной двойки, чисто физически. Даже при работе чрез битовую структуру значение элемента считается в отдельной переменной, и только после ограничения записывается в структуру.

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 20:32 
Старожил

Зарегистрирован: 07 фев 2011, 21:00
Сообщения: 446
Откуда: Ханты-Мансийск
Где-то читал, что по умолчанию в ARM использует прямой порядок байт

оптимизирую свой пример
Show

Цитата:
Асм еще покурю.

Show

за команды push, pop не уверен. раньше в режиме ARM использовал STMED r13!, {r0, r1} и LDMED r13!, {r0, r1}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 20:40 
Старожил
Аватара пользователя

Зарегистрирован: 18 май 2013, 20:43
Сообщения: 3487
Откуда: Кемеровская область, Киселевск
union Data {
uint64_t a;
uint8_t Arr[5];
};

а так?

_________________
RADIOWOLF.RU


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 21:04 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
judchin писал(а):
Где-то читал, что по умолчанию в ARM использует прямой порядок байт
это точно? и в каких именно ARM? Я вроде бы обратный в кортексах-М наблюдал... (но они могут оба)

Oxford писал(а):
union Data {
uint64_t a;
uint8_t Arr[5];
};

а так?
на мой кривой взгляд это тоже самое что и
Код:
*((uint64_t *)Arr)++;

Хотя, получше тем, что не будет портить того, что сразу за массивом. Но в остальном так же.


Последний раз редактировалось h4lf 01 апр 2018, 21:08, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 21:08 
Старожил
Аватара пользователя

Зарегистрирован: 18 май 2013, 20:43
Сообщения: 3487
Откуда: Кемеровская область, Киселевск
ну главное чтобы работала.

_________________
RADIOWOLF.RU


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как инкрементить данные в массиве на С
СообщениеДобавлено: 01 апр 2018, 21:12 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
Oxford, в том то и дело, что будет как-то работать если только обратный порядок в массиве устраивает (и при этом обратный порядок на платформе, а на некоторых может ещё быть и смешанный).


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 36 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB