Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

[uquote="pokk",url="/forum/viewtopic.php?p=3357636#p3357636"]Можете привести примеры гадостей ?[/uquote]
Странная просьба. Эти "гадости" сплошь и рядом на форумах встречаются.
Например :

Код: Выделить всё

#define  DATA_PORT    PORTA ;
А потом пытаются что-то записать :

Код: Выделить всё

DATA_PORT = xxx;
И ломают голову об ругань компилятора.
pokk писал(а):Все время в define ставлю точку с запятой
Это у Вас, по всей видимости, ещё мало опыта. Потом уйдёт от Вас эта привычка.
И от точки запятой откажитесь, и do{}while(0) будете ставить в дефайны, ... :)
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Я тут на хабре наткнулся на извращенческое программирование на Си...

Код: Выделить всё

	int Ox01 = ~-~-~-~-~-~-~-~-~-' ';
	int Ox02 = ((!true)["true"]-(false)["FALSE"])>>true;
	int Ox03 = 'X'/2/2^!*"";
	int Ox04 = ('0'>>!*"")-!*"";
	int Ox05 = (~'!'-~'~')>>!*"">>(2==1==0);
	int Ox06 = ('|'||'|'|'|')["||||||||"]%*"error";
	int Ox07 = '.'>>!false;
	int Ox08 = '\\'>>('!'>>(1<<2));
	int Ox09 = '/'-'/'/'/'>>'/'/'/';
	int Ox0a = (*"")["yes"]^(*"")["no"];
	int Ox0b = *"yes"^*"no";
	int Ox0c = '0'/2-!*"";
	int Ox0d = ((!'!'+'+')>>true)+(true<<true);
	int Ox0e = (-~true^!false)*(true<<(-~true|!false))-!false;
	int Ox0f = '!'-'^'%*"*";
	int Ox10 = -~*" L"^-~*"5Z";
	int Ox11 = *"Totally" -* "not" +* "0x17" + true;
	int Ox12 = -~!*""*-~!*""*-~!*""*-~!*""*-~!*""+~!*""*-~!*""*-~!*""-true;
	int Ox13 = -compl(-compl true xor true)<<-compl true|'8'>>('1'^'2');
	int Ox14 = '^'>>('<'^'>');
	int Ox15 = *"'"-(' '>>!0);
	int Ox16 = '_'>>-~1;
	int Ox17 = 010-001+010+010;
каждая из вышеописанных переменных имеет значение 0x17
это на само деле так.
но блин!!!! я не понимаю...
первый способ получения этого значения я осилил: операции побитовой инверсии вкупе с изменением знака каждый раз отнимают 1 от исходного числа "пробел", т.е. кода этого символа... 9 попарных сочетаний этих операций и дает нужное число.

ну последний вариант тоже очевиден - восьмеричная система счисления...

но вот дальше следуют варианты, от которых пока просто оторопь... можно попросить знатоков Си последовательно, пример за примером, объяснить, как оно работает? :oops:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ARV",url="/forum/viewtopic.php?p=3358453#p3358453"]

Код: Выделить всё

int Ox02 = ((!true)["true"]-(false)["FALSE"])>>true;
[/uquote]
Упрощаем:

Код: Выделить всё

int Ox02 = (0["true"] - 0["FALSE"]) >> 1;
Строки заменяются адресами и компилятору не особо важно что относительно чего индексировать, т.е. остается ('t' - 'F') >> 1

Код: Выделить всё

int Ox03 = 'X'/2/2^!*"";
Тут вообще все просто: 0x58 / 2 / 2 ^ !0

Код: Выделить всё

int Ox04 = ('0'>>!*"")-!*"";
Аналогично: ('0' >> 1) - 1;

Код: Выделить всё

int Ox05 = (~'!'-~'~')>>!*"">>(2==1==0);
(~'!' - ~'~') >> 1 >> 1

Дальше лень разбираться, похоже все примеры достаточно однотипные...
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

после разжёвывания становится всё просто :) в очередной раз я купился на то, что квадратные скобки для индексации массива можно ставить чуть ли не произвольно.

выходит, что str[0] == 0[str]

манипуляции с математикой более-менее понятны, нежели вот это

Код: Выделить всё

int Ox0a = (*"")["yes"]^(*"")["no"];
что такое (*"") - ?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ARV",url="/forum/viewtopic.php?p=3358503#p3358503"]что такое (*"") - ?![/uquote]
Вместо "" будет адрес пустой строки, т.е. *"" дает завершающий 0...
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

я не понял, как тут разыменование происходит.

Добавлено after 1 minute 3 seconds:
сцуко, хотя, пожалуй, понял...

В общем... слушайте, детишки: никогда-никогда-никогда так не пишите!!!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

Код: Выделить всё

const char* s = "";
*s;
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Сообщение Psych »

int Ox16 = '_'>>-~1;
-~1 = 2
'_'>>2=0x17
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

В мне непонятно само int 0x17 = что_то_там;
Вроде же имя переменной с цифры начинается не может, разве не так?
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

WiseLord писал(а):Вроде же имя переменной с цифры начинается не может, разве не так?
оно и начинается с буквы O
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

ах, чёрт.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Перечеркнутый ноль мудрые люди давно придумали.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

На смартфоне разница была почти незаметна:

Изображение
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 7382
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Снова подниму тему глобальных переменых... Прочитал я в этой теме, что это зло, но от него не могу отказаться. Тут один проектик разросся до того, что стал трудно "сопровождаемым" и я решил его побить по модулям. Вот с одной проблемой не знаю как справиться. Выделил в отдельный модуль обработчик клавиш - всё вроде внятно, но есть одна переменная у неё kbddelay - таймер задержки, которая декрементируется в таймерном прерывании. Пока оно было в одном файле - проблем не было. А теперь обработчик прерываний находится в главном файле проекта, а обработчик кнопок в другом. Где эту переменную объявить, описать итд.

Есть еще одна - буфер "видеоозу". Используется в главном модуле и в модуле конфигурации. Конечно, я могу в каждом модуле выделить свой буфер - на функционал не влияет, но прамяти жалко. Пока объявил в main.c а в configure.c написал как extern.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

есть, как говорится, два способа: правильный и удобный :)
удобный - это плевать на то, как говорят, делать так, чтобы работало. но тут следует помнить, что удобно одному, другому будет неудобно. да и собственные привычки могут поменяться с годами...

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

с обработчиками прерываний все похуже, т.к. у них особый статус "невидимок для всех". поэтому, с моей точки зрения, идеальным был бы вариант, когда прерывание для работы с клавиатурой определено в модуле работы с клавиатурой. но если одно прерывание занимается обслуживанием интересов нескольких модулей - так не выйдет. и тут городить излишние "изолирующие прокладки" в виде промежуточных модулей, не очень хорошая идея: попрёт оверхед памяти, снизится производительность... тут нужно искать компромиссы, например, по типу, как у вас
uldemir писал(а):объявил в main.c а в configure.c написал как extern
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

ARV, у тебя с uldemir одна общая проблема - вы мыслите на уровне avr ...
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

[uquote="uldemir",url="/forum/viewtopic.php?p=3361993#p3361993"]есть одна переменная у неё kbddelay - таймер задержки, которая декрементируется в таймерном прерывании. Пока оно было в одном файле - проблем не было. А теперь обработчик прерываний находится в главном файле проекта, а обработчик кнопок в другом. Где эту переменную объявить, описать итд.[/uquote]
объявлять там, где непосредственно используется. Так же иметь в "модуле" функцию, декрементирующую сию переменную, и дергать ее из прерывания или откуда угодно еще.
[uquote="uldemir",url="/forum/viewtopic.php?p=3361993#p3361993"]Есть еще одна - буфер "видеоозу". Используется в главном модуле и в модуле конфигурации. Конечно, я могу в каждом модуле выделить свой буфер - на функционал не влияет, но прамяти жалко[/uquote]
храните и используйте указатели на буфер, заносите в них актуальный адрес при инициализации.

[uquote="ARV",url="/forum/viewtopic.php?p=3362035#p3362035"]с видеоозу, по правильному, не должны работать модули напрямую, как с массивом - только через предназначенные для этого функции. в этом случае и видеоозу, и функции для работы с ним будут в одном модуле, а для других модулей видеоозу существовать не будет - только функции, которые чтото там выводят/рисуют[/uquote]
это даже на "больших" компах далеко не всегда проканывает. Зачастую вывод чего-нибудь графического начинается с обращения к вышележащей софтине (драйверу/интерфейсу/части тулкита) типа "дай мне буфер для непосредственных манипуляций".
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск

Сообщение Chip115 »

Всем привет!
Пытаюсь написать алгоритм работы с SPI EEPROM, но из-за недостатка опыта сомневаюсь в правильности алгоритмов, потому требуется помощь.
Контроллер STM32F103C8 (Reference manual)
Память M95M01 (pdf)
В общем, начал с низкоуровневых функций. Настройка SPI2, поднятие преываний на прием и окончание передачи.
Как я понимаю передача и приём идет одновременно. В интернете полно примеров, но там используются всякие костыли типа

Код: Выделить всё

while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET); 
что, откровенно, вызывает кровь из глаз. Хотя мой быдлокодинг еще больше кровоточит. Ну да ладно, ближе к теме.

В общем, функция для отправки байта

Код: Выделить всё

typedef enum
{
  SPI_EEPROM_STATUS_BSY, 	// Spi is busy
  SPI_EEPROM_STATUS_RDY
} SpiEepromStatus;

typedef struct 
{
  unsigned spiByteReseived: 1;
  unsigned spiByteTransmited: 1;
} SpiState_TypeDef;

SpiEepromStatus ui8EepromSendByte(uint8_t byte)
{
  SpiEepromStatus Status = SPI_EEPROM_STATUS_BSY;
  
  if (SPI2->SR & SPI_SR_TXE)
  {
    SPI2->DR = byte;
    Status = SPI_EEPROM_STATUS_RDY; 
  }
  else	
    Status = SPI_EEPROM_STATUS_BSY;
  
  return Status;
}
Смысл такой, что если циклически вызывать

Код: Выделить всё

ui8EepromSendByte 
и чекать что вернула функция, то можно рулить тем, что бы данные отправлялись тогда, когда предыдущие гарантированно уйдут. Такая конструкция приемлема или есть более интересная реализация?

Функция прерывания

Код: Выделить всё

void SPI2_IRQHandler (void)
{
	if (SPI2->SR & SPI_SR_RXNE)
  	{
           ui8ByteFromSpiEeprom = SPI2->DR;
           vSetSpiEepromFlag (&SpiState, SPI_BYTE_RECEIVED);
	 }
	
	if (SPI2->SR & SPI_SR_TXE)
  	{
           SPI2->SR &= ~SPI_SR_TXE;
  	}
}
vSetSpiEepromFlag взводит флаг в битовом поле (через битбанд). Таким образом происходит обмен мессаджами между функциями.
Реализованное битовое поле

Код: Выделить всё

typedef struct 
{
  unsigned spiByteReseived: 1;
  unsigned spiByteTransmited: 1;
} SpiState_TypeDef;
В целом, цель поднять FAT на SPI EEPROM и определить её как USB, потому в этом контексте, подобная реализация низкоуровневых функций норм? Или же мне отправляемые/принимаемые данные через кольцевой буфер гонять? Или исходящий поток нет смысла через кольцевой буфер гнать? Вообще, общение с EEPROM постраничное? т.е. прежде чем изменить байт (-ты), я должен прочитать всю страницу, изменить нужную информацию и записать вновь?
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Вопрос то не по Сям.
Надо было здесь топик создавать, сразу бы про DMA разговор бы пошел :).
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Ответить

Вернуться в «Разные вопросы по МК»