Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проверка массива на одинаковые элементы 
:(
    Опции темы
supercelt
Дата 4.8.2015, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Привет. 
Кодю под микроконтроллер на си.
Есть массив

Код

unsigned char data[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1......1,1,1}; // 64 единицы в массиве


Ести ли функция что бы проверить что в массиве все 1 или если в массиве все нули, то проверить что все нули?
Что бы не писать циклами.
PM   Вверх
Sartorius
Дата 4.8.2015, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: 2
Всего: 37



Почему бы не хранить это в 8 байтах битами? И проверять будет проще... Функции, конечно, нет такой
Можно memcmp приспособить
Код

bool allZero = pMem[0] == '\0' && !memcmp(pMem, pMem + 1, length - 1);

PM MAIL ICQ   Вверх
borisbn
Дата 5.8.2015, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Код
unsigned char data[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
unsigned int data_size = sizeof( data ) / sizeof( data[ 0 ] );
unsigned int sum = std::accumulate( data, data + data_size, 0 );
if ( sum == data_size ) {
    // all 1
}
if ( sum == 0 ) {
    // all 0
}
else {
    // mixed
}

http://ideone.com/wUGNRI

И, да.. Это будет работать только если в массиве либо 0 либо 1.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 5.8.2015, 14:04 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(supercelt @  4.8.2015,  21:40 Найти цитируемый пост)
 на си.


Код

  unsigned char data[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1......1,1,1}; // 64 единицы в массиве

   if (!memchr (data, 0, sizeof data))
   {
      // все единицы (точнее все "не нули", если кроме 0 и 1 может быть что-то еще)
   }
   else if (!memchr (data, 1, sizeof data))
   {
      // все нули (точнее все "не единицы", если кроме 0 и 1 может быть что-то еще)
   }
   else
   {
      // разные
   }

PM MAIL   Вверх
TarasProger
Дата 5.8.2015, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Это только циклами. Цикл может быть спраятан в функцию, но ведь функция - это не заклятье, её надо реализовать. Ну ещё для меланьких разрядностей и маленького количества элемента можно перетипизировать указатель на масив типом, чья разрядность покрывает весь массив. 
Код
char c[4];
if ((*((uint32_t*)c))==16843009)// Если все 4 по 1
, но если тип вылезает за границы, то хак надо подправить: 
Код
char c[3];
if (((*((uint32_t)c))&0x00FFFFFF)==65793)// Если все 3 по 1
 + надо позабоиться о том, чтоб память за границей массива была в принципе адресуема на чтение, просто масссиву она может не принадлежать. Поэтому этот хак уже грязный, совсем свинячий, в отличие от первого варианта. Но это только для констант хорошо, иначе придётся в коде собирать значение для сравнения по элементам массива.

Это сообщение отредактировал(а) TarasProger - 5.8.2015, 18:57
PM MAIL   Вверх
volatile
Дата 6.8.2015, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(TarasProger @  5.8.2015,  18:52 Найти цитируемый пост)
char c[3];
if (((*((uint32_t)c))&0x00FFFFFF)==65793)// Если все 3 по 1

Цитата(TarasProger @  5.8.2015,  18:52 Найти цитируемый пост)
этот хак уже грязный, совсем свинячий

это не хак, это баг  smile 
при big-endian, работать не будет.
Цитата(supercelt @  4.8.2015,  21:40 Найти цитируемый пост)
Кодю под микроконтроллер 

в данном случае, это как раз вполне реальная ситуация.

 smile
да, и зачем обфусцировать код. (константы в десятичном виде)?

PM MAIL   Вверх
TarasProger
Дата 6.8.2015, 14:35 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Цитата(volatile @  6.8.2015,  10:09 Найти цитируемый пост)
при big-endian, работать не будет
Грязный хак и не должен работать на всём подряд, так как импользуеет для "оптимизации" под вполне определённую целевую платформу только её же особенности. Я сразу предупредил, что способ грязен и в приличном коде не уместен.

Добавлено @ 14:40
Цитата(volatile @  6.8.2015,  10:09 Найти цитируемый пост)
в данном случае, это как раз вполне реальная ситуация.
А что, кроскомпиляторы не раализуют сёвые типы?

Добавлено @ 14:40
Цитата(volatile @  6.8.2015,  10:09 Найти цитируемый пост)
да, и зачем обфусцировать код. (константы в десятичном виде)?
А это то здесь каким боком?

Это сообщение отредактировал(а) TarasProger - 6.8.2015, 14:45
PM MAIL   Вверх
supercelt
Дата 11.8.2015, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Цитата(volatile @ 5.8.2015,  14:04)
Цитата(supercelt @  4.8.2015,  21:40 Найти цитируемый пост)
 на си.


Код

  unsigned char data[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1......1,1,1}; // 64 единицы в массиве

   if (!memchr (data, 0, sizeof data))
   {
      // все единицы (точнее все "не нули", если кроме 0 и 1 может быть что-то еще)
   }
   else if (!memchr (data, 1, sizeof data))
   {
      // все нули (точнее все "не единицы", если кроме 0 и 1 может быть что-то еще)
   }
   else
   {
      // разные
   }

не работает (

Странная штука, я вот делаю вот так: 

Код

volatile unsigned char cmp1[64] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
if (memcmp (cmp1, buffer, 64) == 0){
                    PORTA |= (1 << 0);
                }

buffer содержит в себе : {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}

И прикиньте. Тоже не работает, хотя по описанию функции, если массивы равны, то должно выполнится условие

Это сообщение отредактировал(а) supercelt - 11.8.2015, 13:04
PM   Вверх
volatile
Дата 11.8.2015, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(supercelt @  11.8.2015,  12:49 Найти цитируемый пост)
И прикиньте. Тоже не работает

supercelt, вам не приходила мысль что если не работает ни memchr , ни memcmp , значит ошибка где-то в другом месте?
например буфер не содержит всех единиц, или буфер содержит, но вывод выдает не туда, не так, не там..., и т.д, и т.п.
Под отладчиком не пробовали смотреть?


PM MAIL   Вверх
supercelt
Дата 11.8.2015, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



volatile, Так я и смотрел под ним. И массивы точно совпадают. В просмотрщике переменных видно, буфер забит единицами. Запускаю отладчик по шагам. Курсор приходит на условие сравнивает массивы и выходит из условия, не выполняя то что в нём.
Я тут ещё вычитал что нужно инклудить memory.h, когда используешь ф-ии mem. Хотя на другом сайте написано, что достаточно включить string.h В библиотеке атмела memory.h нету вообще. Погуглил, нигде нету этой библиотеки для СИ 

Это сообщение отредактировал(а) supercelt - 11.8.2015, 17:54
PM   Вверх
volatile
Дата 11.8.2015, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(supercelt @  11.8.2015,  17:49 Найти цитируемый пост)
Я тут ещё вычитал что нужно инклудить memory.h

supercelt, оно бы просто не скомпилилось, если бы не хватало нужных инклудов
раз скомпилилось значит все норм.

Насчет атмеловского компилера, там довольно кривенький компилер.
нельзя зайти в саму функцию memchr или memcmp?
может там какие-то заглушки вместо них?

Вот, у мелкомягких взял простейшую реализацию этих функций. поставь их (переименуй если надо).
Если с этими все ок, значит проблема с атмеловским компилером. (верней с его CRT)

Код

void * memchr (
        const void * buf,
        int chr,
        size_t cnt
        )
{
        while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
                buf = (unsigned char *)buf + 1;
                cnt--;
        }

        return(cnt ? (void *)buf : NULL);
}


int memcmp (
        const void * buf1,
        const void * buf2,
        size_t count
        )
{
        if (!count)
                return(0);

        while ( --count && *(char *)buf1 == *(char *)buf2 ) {
                buf1 = (char *)buf1 + 1;
                buf2 = (char *)buf2 + 1;
        }

        return( *((unsigned char *)buf1) - *((unsigned char *)buf2) );
}


По крайней мере с этими ты пошагам сможешь пройти, и посмотреть что происходит.

Это сообщение отредактировал(а) volatile - 11.8.2015, 18:51
PM MAIL   Вверх
supercelt
Дата 11.8.2015, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



спасибо большое memcmp работает. Я так понял что она возвращает 0, если массивы равны да? 
PM   Вверх
volatile
Дата 11.8.2015, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(supercelt @  11.8.2015,  19:13 Найти цитируемый пост)
Я так понял что она возвращает 0, если массивы равны да?  

да

в гугле набираешь одно слово memcmp, первая же ссылка
http://www.cplusplus.com/reference/cstring/memcmp/
лучше вряд ли кто объяснит. (совет  smile )
PM MAIL   Вверх
TarasProger
Дата 12.8.2015, 06:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Цитата(supercelt @  11.8.2015,  17:49 Найти цитируемый пост)
Я тут ещё вычитал что нужно инклудить memory.h, когда используешь ф-ии mem. Хотя на другом сайте написано, что достаточно включить string.h В библиотеке атмела memory.h нету вообще. Погуглил, нигде нету этой библиотеки для СИ 
Какое дело может быть в инкладе? А очень простое: функция может быть не известна компилятору. Но тогда код бы не скомпилировался. Значит декларация или дублирована в заинклаженной голове, или та голова сама инкладит нужную.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0573 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.