Например TDA7294

Форум РадиоКот • Просмотр темы - Вопросы по С/С++ (СИ)
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Ср ноя 12, 2025 19:46:17

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


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 7702 ]     ... , , , 266, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб мар 03, 2018 00:58:28 
Потрогал лапой паяльник
Аватар пользователя

Карма: 20
Рейтинг сообщений: 121
Зарегистрирован: Вс янв 19, 2014 22:41:55
Сообщений: 353
Рейтинг сообщения: 0
но вот беда... не могу посимвольно читать строку...
Что-то тут не так:
Код:
for(i=0;i<strlen(Font[C].Lines);i++)
  {
      if  (Font[C].Lines[i]!="|") { }
  }

Буквально формально но длина строчки будет пере-strlen-иться на каждой итерации цикла. Оптимизатор, конечно, дремать не будет - но иные пожилые обитатели сего места могут и инфаркт схватить почём зря увидев такое. Но это лирика и оффтоп. Обращение-же ваше к i-тому элементу строки Lines по индексу вполне легально - Lines это указатель и его можно читать как кому нравится - хоть массивно, хоть адресно-арифметично. Но, - Сравниваете вы с адресом строкового литерала "|" а не с байтом 0х7C как задумывалось. Для символьных литералов нужно использовать одиночные кавычки. В качестве мелкого пятничного издевательства вот вам немножко Ъ-шных пере-интерпретаций вашей идеи. Для разминки. :-)
Код:
char* p = NULL;
for (p = Font[C].Lines; *p; p++) {
   if  (*p != '|') { }
}

Но подход ваш зело эклектичный, и знание дельфи никак не освобождает от необходимости понимания сути творимых вещей. Так строчки в С - это последовательности байтов, которые завершаются нулём. И strlen в общем случае будет тупо перебирать их от начала до конца - а вы это в условие цикла вставили - видимо чтобы МК не скучал в главном цикле программы. ;) А "|" это строковая константа и состоит она из двух байтов 0x7C 0x00. И тип у этой константы const char*. А операция взятия элемента массива (в нашем случае строки char-ов) по индексу возвращает нам значение типа char. А вы его сравниваете с const char* - а для компилятора это всё равно как вам на завтрак огурцы солёные с молочком кто предложит, чтобы день прошёл не зазря.

_________________
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб мар 03, 2018 02:58:47 
Друг Кота

Карма: 38
Рейтинг сообщений: 618
Зарегистрирован: Пн апр 06, 2015 11:01:53
Сообщений: 3092
Откуда: москва, уфа
Рейтинг сообщения: 0
оффтоп
храниить шрифт в текстовом виде?! до этого даже в Майкрософте не додумались!

никто так не делает, да, но емнип патент на такое безумство таки есть)

Shrike, у вас в чем конкретно проблема? Первоначально - в ваших строках вида "010516364541301001|0541" все эти "01", "05", "16" и так далее по задумке должны соответстовать числам 1, 5, 16, или таки по счастливой случайности являются какими-никакими корректными строковыми представлениями двухбайтовых чисел?)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб мар 03, 2018 13:46:10 
Родился

Зарегистрирован: Пт мар 02, 2018 16:31:19
Сообщений: 7
Рейтинг сообщения: 0
Спасибо всем, кто откликнулся и оказал помощь!

"01", "05", "16" это пара координат точек полилиний: (x=0;y=1); (x=0;y=5); (x=1;y=6) ... по оси х больше 4 не бывает, по у - не более 7. Шрифт 4х6 и хвосты у некоторых символов до 7
На глубокое изучение языка Си просто нет времени, для хобби "и так сойдет" =)
Задумку реализовать получилось, в качестве примера приведу фото дисплея с парочкой символов в оригинальном масштабе и в масштабе 7.5
Код приводить не буду, дабы, как написал Siarzhuk, "пожилые обитатели сего места могут и инфаркт схватить почём зря увидев такое" =)))

Следующий этап - антиалайзинг. Если интересно, могу выложить результаты.


Вложения:
Комментарий к файлу: Фото дисплея
IMG_20180303_143230.jpg [182.54 KiB]
Скачиваний: 418
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб мар 03, 2018 14:55:58 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4590
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Shrike1987 писал(а):
"01", "05", "16" это пара координат точек полилиний ... по оси х больше 4 не бывает, по у - не более 7.
Вашу пару можно сократить до 1 байта, при таких условиях.
Код:
typedef struct{
  unsigned char   x:3;
  unsigned char   y:3;
}t_point;


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб мар 03, 2018 15:01:34 
Потрогал лапой паяльник
Аватар пользователя

Карма: 20
Рейтинг сообщений: 121
Зарегистрирован: Вс янв 19, 2014 22:41:55
Сообщений: 353
Рейтинг сообщения: 0
по оси х больше 4 не бывает, по у - не более 7. Шрифт 4х6 и хвосты у некоторых символов до 7

Ну как закончится память - приходите заслушать про битовые поля. :)
На глубокое изучение языка Си просто нет времени, для хобби "и так сойдет" =)

Будь такое сказано про С++ - возможно и прокатило-бы, но в С "глубоко" изучать попросту нечего - умели Люди делать инструмент в своё время. :-)
Задумку реализовать получилось, в качестве примера приведу фото дисплея с парочкой символов в оригинальном масштабе и в масштабе 7.5

Думаю не я один сейчас злорадно ухмыльнулся, зная как оно там у вас "оптимально" устроено, в желании задать вопрос: -"Кабы, барин, видео посмотреть. А фоточками сыт не будешь, вестимо." ;-)

_________________
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб мар 03, 2018 17:35:00 
Говорящий с текстолитом
Аватар пользователя

Карма: 33
Рейтинг сообщений: 148
Зарегистрирован: Вс июн 24, 2012 16:07:00
Сообщений: 1590
Откуда: Лен.Обл.
Рейтинг сообщения: 0
Цитата:
Вашу пару можно сократить до 1 байта, при таких условиях.


И дописав
Код:
#pragma pack(1)
...
typedef struct
{
};
...

#pragma pack()


Иначе фокус может не получиться. :)

_________________
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб мар 03, 2018 21:22:12 
Родился

Зарегистрирован: Пт мар 02, 2018 16:31:19
Сообщений: 7
Рейтинг сообщения: 0
Уважаемые гуру!
Я прекрасно понимаю, что у меня дико криво реализован алгоритм хранения векторного шрифта, впрочем, как и его прорисовка. Я понимаю, что по хорошему пару координат нужно хранить в 1 байте. Но, мне крайне тяжело и долго нужно будет разбираться в том, как создать тип данных в виде структуры с динамическим массивом и этот тип назначить статическому массиву. Сама сложность для меня состоит в самом понимании где и когда нужно использовать указатель, выделять память, освобождать... При всем этом самого синтаксиса не знаю... Ну да ладно, будет время - разберемся. Правда в том, что действительно времени может и не быть, но возникнет необходимость.

По поводу видео: могу конечно записать, только что именно? пока у меня реализовано 25 символов и функция void DrawChar(uint8_t C, uint16_t X, uint16_t Y, float scale), где C - индекс символа.

Добавлено after 11 minutes:
Решил все же показать код, только рассматривайте его как анекдот, не принимайте близко к сердцу =)

Так объявлен тип и переменная:
Код:
#pragma pack(1)
struct TFont {
  char *Lines;
} Font[255] ;
#pragma pack()

Так заполняется шрифт векторами:
Код:
   Font[48].Lines="010516364541301001|0541";                    // 0
   Font[49].Lines="112026|1636";                                      // 1
   Font[50].Lines="01103041420646";                                // 2
   Font[51].Lines="0040224445361605";                               // 3
   Font[52].Lines="3630030444";                                        // 4
   Font[53].Lines="400002324345361605";                            // 5
   Font[54].Lines="4130100105163645443303";                      // 6
   Font[55].Lines="0004412326";                                        // 7
   Font[56].Lines="103041423344453616050413020110|1333"; // 8
   Font[57].Lines="0516364541301001021343";                      // 9

А вот так отрисовывается символ:
Код:
void DrawChar(uint8_t C, uint16_t X, uint16_t Y, float scale)
{
   uint8_t i;
   uint8_t xo=255;
   uint8_t yo=255;
   uint8_t xn=255;
   uint8_t yn=255;
   uint8_t n=0;
   uint8_t nl=0; //new line
   uint8_t k=48;
   
   for(i=0; i<strlen(Font[C].Lines); i++)
  {
      if (Font[C].Lines[i]!="|"[0])
         {
            if (n%2==0) {xo=xn; xn=Font[C].Lines[i]; nl=0;}
            if (n%2==1) {yo=yn; yn=Font[C].Lines[i]; nl=1;}
            n++;
         }  else
      {
            xo=255;
            yo=255;
            xn=255;
            yn=255;
            nl=0;
         }
      if ((nl==1) && (xo<255) && (yo<255))
         {
            drawLine(X+xo*scale-k*scale,Y+yo*scale-k*scale,X+xn*scale-k*scale,Y+yn*scale-k*scale,Color565(255,255,255));
            nl=0;
         }
  }
}


Может найдется тот, кто сделает из этого конфетку...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Сб мар 03, 2018 23:49:05 
Потрогал лапой паяльник
Аватар пользователя

Карма: 20
Рейтинг сообщений: 121
Зарегистрирован: Вс янв 19, 2014 22:41:55
Сообщений: 353
Рейтинг сообщения: 0
Иначе фокус может не получиться. :)

Зачем паковать байт? Байт он всегда байт - как его ни пакуйте - а sizeof(t_point) в конкретном случае будет 1. Биты 0-2 отводятся под x, а 3-5 - под y. Биты-же 6,7 остаются неиспользуемы при любом раскладе кроме явного их указания в качестве поля(пары полей) размером 2 бита (либо по биту). Поле размером 3 бита займёт уже 0-2 биты следующего байта.

Код:
struct t_point {
   unsigned char x : 3;
   unsigned char y : 3;
   unsigned char z : 3;
};

   unsigned char bb[2] = { 0 };

   struct ccc* c = (struct ccc*)bb;

                  // содержимое bb -> 0х00, 0x00
   c->x = 0x07;   // содержимое bb -> 0х07, 0x00
   c->y = 0x07;   // содержимое bb -> 0х3F, 0x00
   c->z = 0x07;   // содержимое bb -> 0х3F, 0x07
   


Для того-же, чтобы все биты лежали плотнячком - придется объявлять базовый тип поля пошире - т.е. unsigned short как минимум. Но, любителей накладывать такие "широкие" битовые маски на сырые данные прилетевшие из внешнего мира ждут некоторые сюрпризы - особенно на "остроконечниковых" (low endian) платформах. Да даже уже и в нашем примере пытливый глаз наверняка обнаружил некоторую странность - отчего-то "младшие" x,y лежат перед "старшим" z, не так-ли? :-)

А вот вариант с short -ом:

Код:
struct t_point {
   unsigned short x : 3;
   unsigned short y : 3;
   unsigned short z : 3;
};

   union uu {
      unsigned char   bb[2];
      unsigned short  s;
   } u  = { 0 };

   struct sss* c = (struct sss*)&u;
                  // содержимое u.bb -> 0х00, 0x00, содержимое u.s -> 0х0000
   c->x = 0x07;   // содержимое u.bb -> 0х07, 0x00, содержимое u.s -> 0х0007
   c->y = 0x07;   // содержимое u.bb -> 0х3F, 0x00, содержимое u.s -> 0х003F
   c->z = 0x07;   // содержимое u.bb -> 0хFF, 0x01, содержимое u.s -> 0х01FF
   

Биты уплотнились как надо - но в байтовом массиве по прежнему "бардачат", а вот как unsigned short всё прекрасно - потому как собирал я этот примерчик на LE платформе.

Грустные выводы - не все возможные комбинации можно представить в битовых полях, а для low endian придётся порой ещё и байты в исходных данных переставлять (для кайловских ARM тулчейнов, кстати, есть интриниксы _REV16, _REV32)

Добавлено after 1 hour 11 minutes 1 second:
Но, мне крайне тяжело и долго нужно будет разбираться в том, как создать тип данных в виде структуры с динамическим массивом и этот тип назначить статическому массиву.

С - это высокоуровневый ассемблер - понимая как компилятор с компоновщиком строят образ программы вы будет знать как работает железяка. Без всякой магии. Дело стоящее - не исключайте для себя такую возможность. :-D
Код:
typedef struct {
   unsigned char x    : 3; // 0x00 - 0x07
   unsigned char brk : 1; // 0x08
   unsigned char y    : 3; // 0x00 - 0x70
   unsigned char eol : 1; // 0x80
} t_point;

#define BRK  0x08
#define EOL  0x80

// [омномномном]

//   Font[55].Lines="0004412326";                                        // 7
const t_point ch55[] = { 0x00, 0x04, 0x41, 0x23, 0x26, EOL } ; // 7

//   Font[56].Lines="103041423344453616050413020110|1333"; // 8
const t_point ch56[] = { 0x10, 0x30, 0x41, 0x42, 0x33, 0x44, 0x45, 0x36, 0x16, 0x05, 0x04, 0x13, 0x02, 0x01, 0x10, BRK, 0x13, 0x33, EOL } ; // 8

//   Font[57].Lines="0516364541301001021343";                      // 9
const t_point ch57[] = { 0x05, 0x16, 0x36, 0x45, 0x41, 0x30, 0x10, 0x01, 0x02, 0x13, 0x43, EOL } ; // 9

// [омномномном]

const struct TFont {
   const t_point *Line;
} Font[255]  = {
   ch00, ch01, ch02,   и.т.д, и т.д.....           ,  ch56, ch57,
};


Всё вышеприведенное объявляется в глобальной области (не в функциях!) - и вся работа будет сделана компилятором - функции DrawChar остаётся только воспользоваться уже набитым массивом данных. И не забудьте терминировать все данные символов байтом EOL - иначе оно отрисует вам содержимое всей памяти аж до случайно встреченного символа с установленным верхним битом. :-)

Код:
void DrawChar(uint8_t C, uint16_t X, uint16_t Y, float scale)
{
   t_point* p0 = NULL;
   t_point* p = NULL;

   for (p0 = Font[C].Line, p = Font[C].Line + 1; 0 == p->eol; p0 = p, p++) {
      if (0 != p->brk )
         continue;

      drawLine( X + p0->x * scale - k * scale,
            Y + p0->y * scale - k * scale,
            X + p->x * scale - k * scale,
            Y + p->y * scale - k * scale,
            Color565(255, 255, 255));
   }
}

По поводу видео: могу конечно записать, только что именно?

Не заморачивайтесь - подкалывал я вас. Скорость работы программы оценивается [тупым] юзером по времени отклика системы на его хотелки - и если шрифт рисуется с заметным анимационным эффектом - это медленная система с его [тупой] точки зрения. А если глаз не замечает - то и чёрт с ним - занимается ли там МК парсингом ваших строковых литералов на лету или просто хомячит инструкции в бесконечности главного цикла - всё едино лепота. ;-)
Решил все же показать код, только рассматривайте его как анекдот, не принимайте близко к сердцу =)

Как по мне так это было правильное решение с вашей стороны.
Да, и ещё по описанию вектора отрисовки символа - идею с размещением х и y в полубайтах для большей наглядности вы поняли, кстати?

_________________
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 07:28:28 
Говорящий с текстолитом
Аватар пользователя

Карма: 33
Рейтинг сообщений: 148
Зарегистрирован: Вс июн 24, 2012 16:07:00
Сообщений: 1590
Откуда: Лен.Обл.
Рейтинг сообщения: 0
Цитата:
Зачем паковать байт? Байт он всегда байт - как его ни пакуйте - а sizeof(t_point) в конкретном случае будет 1.


В вашем конкретном случае будет. А в общем случае - нет. Поэтому если у вас есть структура и вы хотите минимизировать размер занимаемой ею памяти, то всегда следует включать выравнивание к одному байту.
Цитата:
Код:
struct ccc* c = (struct ccc*)bb;

                  // содержимое bb -> 0х00, 0x00
   c->x = 0x07;   // содержимое bb -> 0х07, 0x00
   c->y = 0x07;   // содержимое bb -> 0х3F, 0x00
   c->z = 0x07;   // содержимое bb -> 0х3F, 0x07


Опасная вещь.
Цитата:
Стандарт не определяет:
— The alignment of the addressable storage unit allocated to hold a bit-field
И отдает на откуп компиляторам:
— Whether a ‘‘plain’’ int bit-field is treated as a signed int bit-field or as an
unsigned int bit-field
— Allowable bit-field types other than _Bool, signed int, and unsigned int
— Whether atomic types are permitted for bit-fields
— Whether a bit-field can straddle a storage-unit boundary
— The order of allocation of bit-fields within a unit
— The alignment of non-bit-field members of structures. This should present
no problem unless binary data written by one implementation is read by another.

https://habrahabr.ru/post/142662/

_________________
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 08:56:05 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
Доброго времени суток. Прошу помощи. Почему код
Код:
      uint8_t i;

      for (i = 0; i < 4; i++)
      {
         spi_put(0);
         spi_wait();
         keys[i] = TM1638_convert_byte(spi_get());
      }

не работает так же как код
Код:
      spi_put(0);
      spi_wait();
      keys[0] = TM1638_convert_byte(spi_get());

      spi_put(0);
      spi_wait();
      keys[1] = TM1638_convert_byte(spi_get());

      spi_put(0);
      spi_wait();
      keys[2] = TM1638_convert_byte(spi_get());

      spi_put(0);
      spi_wait();
      keys[3] = TM1638_convert_byte(spi_get());


В дизасме видно, что во втором случае при присваению элементу массива последовательно вызываются 2 функции, а в первом только 1:
Спойлер
Код:
223:               spi_put(0);
+000000B7:   E080        LDI       R24,0x00       Load immediate
+000000B8:   D0A9        RCALL     PC+0x00AA      Relative call subroutine
224:               spi_wait();
+000000B9:   D0D3        RCALL     PC+0x00D4      Relative call subroutine
225:               keys[keys_code] = TM1638_convert_byte(spi_get());
+000000BA:   D0CF        RCALL     PC+0x00D0      Relative call subroutine
+000000BB:   5011        SUBI      R17,0x01       Subtract immediate
221:            for (keys_code = 0; keys_code < 4; keys_code++)
+000000BC:   F7D1        BRNE      PC-0x05        Branch if not equal
229:            spi_put(0);
+000000BD:   E080        LDI       R24,0x00       Load immediate
+000000BE:   D0A3        RCALL     PC+0x00A4      Relative call subroutine
230:            spi_wait();
+000000BF:   D0CD        RCALL     PC+0x00CE      Relative call subroutine
231:            keys[0] = TM1638_convert_byte(spi_get());
+000000C0:   D0C9        RCALL     PC+0x00CA      Relative call subroutine
+000000C1:   DF74        RCALL     PC-0x008B      Relative call subroutine
+000000C2:   2F08        MOV       R16,R24        Copy register


Код всей функции:
Спойлер
Код:
uint8_t TM1638_get_keys(void)
{
   uint8_t keys_code,key_number;
   uint8_t keys[4] = { 0 };
   
   TM1638_STB_LOW();   
   TM1638_write_byte(TM1638_CMD_READ_KEYS);
//   _delay_us(2);                                          // Минимально необходимая по даташиту задержка 2 мкс - можно убрать, все равно есть задержка после поднятия CLK в процедуре записи байта
#ifdef   USE_USI_FOR_TM1638
   half_spi_init_receive();                                 // Init SPI driver as RECEIVED master.
   _delay_us(100);
#else
   TM1638_DIO_INPUT();                                       // Установим ногу на вход !!!
#endif

#ifdef   USE_USI_FOR_TM1638

      for (keys_code = 0; keys_code < 4; keys_code++)
      {
         spi_put(0);
         spi_wait();
         keys[keys_code] = TM1638_convert_byte(spi_get());
      }

/*   ВОТ ТАКОЙ КОД РАБОТАЕТ КАК НАДО   
      spi_put(0);
      spi_wait();
      keys[0] = TM1638_convert_byte(spi_get());

      spi_put(0);
      spi_wait();
      keys[1] = TM1638_convert_byte(spi_get());

      spi_put(0);
      spi_wait();
      keys[2] = TM1638_convert_byte(spi_get());

      spi_put(0);
      spi_wait();
      keys[3] = TM1638_convert_byte(spi_get());
*/

#else
   
   for (keys_code = 0; keys_code < 4; keys_code++)                  // Будем читать 4 байта состояний кнопок
   {
      for (key_number = 0; key_number < 8; key_number++)            // Перебор всех кнопок этого байта
      {
         TM1638_CLK_LOW();
         _delay_us(TM1638_DELAY_US);
         TM1638_CLK_HIGH();

         if (TM1638_DIO_READ())                              // Если есть нажатая кнопка
         {
            keys[keys_code] |= (1<<key_number);                  // Устанавливаем в ЭТОМ байте бит ЭТОЙ кнопки
         }

         _delay_us(TM1638_DELAY_US);         
      }
   }
#endif

   TM1638_STB_HIGH();

#ifdef   USE_USI_FOR_TM1638
   half_spi_reinit_transmit();                                 // Init SPI driver as TRANSMIT master.

#else
   TM1638_DIO_OUTPUT();                                    // Вернем ногу на выход !!!
#endif

   _delay_us(TM1638_DELAY_US);

   TM1638_send_comm(TM1638_CMD_SET_DATA | TM1638_SET_DATA_F_ADDR);      // Установка режима работы - Запись в индикатор, Фиксированный адрес

   _delay_us(TM1638_DELAY_US);

   keys_code = keys[0] | (keys[1]<<1) | (keys[2]<<2) | (keys[3]<<3);   // Собираем состояние всех кнопок в 1 байт (0 и 4 бит каждого из 4 принятых байт)

#ifdef RETURN_KEY_NUMBER
   if (keys_code)                                          // Если нажата кнопка - вычисляем ее номер (Внимание, будет передана только 1, самая младшая кнопка !!!)
   {
      for (key_number = 0; key_number < 8; key_number++, keys_code >>=1)
      {
         if (keys_code & 0x01)                              // Если 0 бит установлен, найдена нажатая кнопка (Внимание, первой будет найдена кнопка из младшего бита)
         {
            return key_number+1;                           // Возвращаем порядковый номер первой найденой нажатой кнопки
         }            
      }
   }
#endif

   return keys_code;                                       // Возвращаем состояние всех кнопок
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 10:12:19 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4590
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
da-nie писал(а):
Цитата:
как его ни пакуйте - а sizeof(t_point) в конкретном случае будет 1.
В вашем конкретном случае будет. А в общем случае - нет.
Хотелось бы увидеть пример такого случая, при котором sizeof(t_point) будет не равен 1. Можете привести ?

da-nie писал(а):
Поэтому если у вас есть структура и вы хотите минимизировать размер занимаемой ею памяти, то всегда следует включать выравнивание к одному байту.
Размер структуры = 1 байт. Куда дальше минимизировать ?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 10:39:47 
Потрогал лапой паяльник
Аватар пользователя

Карма: 20
Рейтинг сообщений: 121
Зарегистрирован: Вс янв 19, 2014 22:41:55
Сообщений: 353
Рейтинг сообщения: 0
В вашем конкретном случае будет. А в общем случае - нет. Поэтому если у вас есть структура и вы хотите минимизировать размер занимаемой ею памяти, то всегда следует включать выравнивание к одному байту.

К байту, а мы речь ведём о битах. И включать его следует не всегда а лишь тогда когда данный эффект требуется - при обмене с внешним миром если структура данных жёстко определена не нами да в случае очень уж сиротских ресурсов у нас - когда в .data уже 0, а в .text ещё место есть и можно заколоть корову эффективности, чтобы вымолить пару байт на данные (битовые поля в ту же кассу кстати работают иногда). Ну и из эстетических соображений - зело уродски выглядит как на мой взгляд. ;-)

Опасная вещь.

Не опаснее указателя. :lol: А про платформо-зависимость я даже на пальцах фокусы показал.

_________________
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 10:55:55 
Говорящий с текстолитом
Аватар пользователя

Карма: 33
Рейтинг сообщений: 148
Зарегистрирован: Вс июн 24, 2012 16:07:00
Сообщений: 1590
Откуда: Лен.Обл.
Рейтинг сообщения: 0
Цитата:
Хотелось бы увидеть пример такого случая, при котором sizeof(t_point) будет не равен 1. Можете привести ?


Любая структура, в которую вы кроме имеющихся битовых полей добавите дополнительные данные. В вашем частном случае структура имеет размер 1 байт. Но если потом будут добавлены дополнительные элементы (а это часто требуется - скажем, добавят цвет), то может проявиться выравнивание структур и структура окажется не минимального достижимого размера. Поэтому стоит всегда дописывать указание компилятору на выравнивание структур.

Цитата:
Размер структуры = 1 байт. Куда дальше минимизировать ?


Это он сейчас один байт. Программы имеют свойство развиваться и структуры имеют свойство изменяться. Бывает даже, что копируются структуры из старой программы и дорабатываются в новой. И вот тогда размер не будет один байт. А вот насколько он окажется больше ожидаемого зависит от выравнивания. При этом вы можете даже и не заметить, что потеряли достаточно много памяти всего лишь добавив к этой структуре, например, 32 битный цвет точки и создав штук 100 таких структур (800-500=300 байт потеряно впустую). #pragma pack(1) спасёт от этой проблемы.

_________________
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 11:02:20 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4590
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
da-nie писал(а):
Это он сейчас один байт.
Аlex писал(а):
Вашу пару можно сократить до 1 байта, при таких условиях.
:)

Ежу понятно, что если в структуру добавить ещё поля, она увеличится в размерах. Но почему её в данном виде нужно паковать, Вы нам секрет так и не открыли.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 11:04:33 
Говорящий с текстолитом
Аватар пользователя

Карма: 33
Рейтинг сообщений: 148
Зарегистрирован: Вс июн 24, 2012 16:07:00
Сообщений: 1590
Откуда: Лен.Обл.
Рейтинг сообщения: 0
Цитата:
К байту, а мы речь ведём о битах. И включать его следует не всегда а лишь тогда когда данный эффект требуется - при обмене с внешним миром


Не только. Если у вас, например, на atmega8 есть крошечное ОЗУ, то создав массив структур вы потеряете довольно много памяти.

Цитата:
Ну и из эстетических соображений - зело уродски выглядит как на мой взгляд.


Если для вас главное - минимизация размера памяти, занимаемых структурой, то этот подход избавит от незамеченного увеличения размера структуры только потому, что вы что-то в неё добавили.

Цитата:
Не опаснее указателя.


Опаснее. Указатель редко используют не по назначению (скажем, разность указателей брать весьма опасно, но так, обычно, и не делают).
Это хорошо, когда процессор достаточно обычный. А у меня вот валяется 1967ВЦ1Т. У него в компиляторе байт 32-битный.


Цитата:
Ежу понятно, что если в структуру добавить ещё поля, она увеличится в размерах. Но почему её в данном виде нужно паковать, Вы нам секрет так и не открыли.


Потому что если вы добавите туда ещё поле с unsigned long Color, то размер будет не 5, а 8 без #pragma pack(1). И 5 с #pragma pack().
А в конкретном виде, как у вас, её нужно выравнивать потому, чтобы в дальнейшем избежать сюрпризов. Это просто рекомендация на будущее, чтобы не было потом мучительно больно.

_________________
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos


Последний раз редактировалось da-nie Вс мар 04, 2018 11:05:14, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 11:06:46 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4590
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
da-nie писал(а):
Поэтому стоит всегда дописывать указание компилятору на выравнивание структур.
Не стоит этого делать всегда, не говорите ерунды. Упаковывать структуры нужно только в крайне необходимых ситуациях.

Добавлено after 1 minute 35 seconds:
da-nie писал(а):
А в конкретном виде, как у вас, её нужно выравнивать потому, чтобы в дальнейшем избежать сюрпризов.
О каких сюрпризах идёт речь ? То, что структура займёт больше памяти ? :)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 11:07:46 
Говорящий с текстолитом
Аватар пользователя

Карма: 33
Рейтинг сообщений: 148
Зарегистрирован: Вс июн 24, 2012 16:07:00
Сообщений: 1590
Откуда: Лен.Обл.
Рейтинг сообщения: 0
Цитата:
Не стоит этого делать всегда, не говорите ерунды. Упаковывать структуры нужно только в крайне необходимых ситуациях.


У вас задача стоит в уменьшении размера памяти. Вреда от #pragma pack(1) в вашем случае у вас всё равно не будет (он не повлияет на ваш вариант, но может повлиять при модификации структуры).

Добавлено after 48 seconds:
Цитата:
О каких сюрпризах идёт речь ? То, что структура займёт больше памяти ?


Да. В условиях этой памяти в 1 кб это может быть очень важно.

P.S. Соврал, не 1967ВЦ1Т - тоже ВЦ, но по-другому как-то называется. Аналог процессора середины 80-х. Мерзость, короче.

_________________
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 11:23:12 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4590
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Вы увиливаете от темы, ссылаясь на "потом". Не будет у человека никаких "потом". У него есть конкретные условия, при которых ему был предложен вариант ужать координаты до 1 байта, вместо им используемых 2-ух. И почему, в конкретном случае (!), без #pragma pack это должно не получиться ("Иначе фокус может не получиться") - до сих пор остаётся загадкой.

Добавлено after 6 minutes 49 seconds:
PS: Не подумайте ничего плохого, я этот диалог развил не ради того, чтобы пообщаться от безделия. Просто Вас читают люди, и совет "нужно всегда упаковывать", чтобы потом не нарваться на какие-то там грабли - очень плохой. Нужно говорить "никогда не упаковывайте без надобности" !


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 11:23:16 
Говорящий с текстолитом
Аватар пользователя

Карма: 33
Рейтинг сообщений: 148
Зарегистрирован: Вс июн 24, 2012 16:07:00
Сообщений: 1590
Откуда: Лен.Обл.
Рейтинг сообщения: 0
Цитата:
И почему, в конкретном случае (!), без #pragma pack это должно не получиться ("Иначе фокус может не получиться") - до сих пор остаётся загадкой.


Читайте внимательнее - "фокус может не получиться". Я не утверждал, что в конкретном случае не получится.

Цитата:
Вы увиливаете от темы, ссылаясь на "потом".


Вообще-то, жизненный цикл программы это самое "потом" предполагает всегда. Знаете, как часто могут перетряхиваться самые простые структуры данных в программе? Добавили одно - убрали другое. Поменяли дисплей на с большим разрешением - не хватает старого размера битового поля для координат. И так далее. Ещё раз для тех, кому обедню два раза не служат: хорошим тоном при желании минимизировать объём структуры будет указание выравнивания к 1 байту с самого начала. Иначе потом, по мере развития проекта, может оказаться, что память уже исчерпана, а вы и не заметили, почему.

Цитата:
PS: Не подумайте ничего плохого, я этот диалог развил не ради того, чтобы пообщаться от безделия. Просто Вас читают люди, и совет "нужно всегда упаковывать", чтобы потом не нарваться на какие-то там грабли - очень плохой. Нужно говорить "никогда не упаковывайте без надобности" !


А я подумаю именно плохое. ;) Потому что у меня такой коллега есть - он всегда отвечает и ругается на то, чего ему никто не говорил и он по сути просто так понял, домыслив часть сам. Совет был дан для случая, когда вам нужно минимизировать объём занимаемой памяти - разве вы не этим занимались? А так - выравнивание ни к чему плохому не приведёт, кроме как к возможному снижению производительности.

_________________
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos


Последний раз редактировалось da-nie Вс мар 04, 2018 11:26:55, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс мар 04, 2018 12:42:36 
Потрогал лапой паяльник
Аватар пользователя

Карма: 20
Рейтинг сообщений: 121
Зарегистрирован: Вс янв 19, 2014 22:41:55
Сообщений: 353
Рейтинг сообщения: 0
Цитата:
К байту, а мы речь ведём о битах. И включать его следует не всегда а лишь тогда когда данный эффект требуется - при обмене с внешним миром

Не только. Если у вас, например, на atmega8 есть крошечное ОЗУ, то создав массив структур вы потеряете довольно много памяти.

Это то, что вы из моих слов отцитировали. А теперь, внимание, моя фраза полностью:
К байту, а мы речь ведём о битах. И включать его следует не всегда а лишь тогда когда данный эффект требуется - при обмене с внешним миром если структура данных жёстко определена не нами да в случае очень уж сиротских ресурсов у нас - когда в .data уже 0, а в .text ещё место есть и можно заколоть корову эффективности, чтобы вымолить пару байт на данные.

[За кулисами слышен плач канделябра в вашу сторону.] Т.е. вы мне оппонируете тем, что я же и озвучил [опуская мой ©] - это несеръёзно. Точно также как возводить в аксиому заклинание "прагма пак - ставь всегда". В большинстве случаев это только снижает производительность при работе с данными. А если носитель памяти имеет ограничения по выравниванию доступа, то [при дурном компиляторе] тот, кто вам доверился потратит некоторое время своей жизни на поиск источника проблемы. Так что, несите людям знания, а не молитвы. ;-)

_________________
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 7702 ]     ... , , , 266, , , ...  

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


Кто сейчас на форуме

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


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

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


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y