diod.club diod.club
Проектирование, изготовление, ремонт и обслуживание электроники
 Помощь   


 Страниц (1): [1]   

> Без описания
Буратино
  Отправлено: 11 Февраля, 2015 - 18:47:38
Post Id
Newbie  (38)
Репутация: 0

Предлагаю обсуждать в данной теме все что касается культового языка Си

Ритчи, Деннис

(Отредактировано автором: 11 Февраля, 2015 - 19:23:01)

Victor_P.
  Отправлено: 14 Апреля, 2015 - 11:03:02
Post Id
Junior Member  (67)
Откуда: Хорол, Україна
Репутация: 1

Знатоки Си, обьясните, какое преимущество дает применение указателей вместо прямого обращения к пременной. С массивами, там более-менее понятно.
Вот, допустим, обьявляю я указатель на переменную
int a;
int* pa = &a;
и что дальше?
ну могу я в коде присвоить значение переменной а через указатель
*pa = 100;
и какой выиграш это мне дает относительно прямого присвоения a=100;?
Можно, конечно, этот указатель переуказать на другую переменную, но опять-же зачем?
Вот такой вот вопрос. Улыбка
koyodza
  Отправлено: 14 Апреля, 2015 - 11:47:53
Post Id
Advanced Member  (313)
Откуда: Kyiv
Репутация: 7

В таком простом примере никакого преимущества нет, скорее только недостатки. Практическая польза от указателей появляется в более сложных случаях. Например, удобно использовать указатели на структуры при разборе буфера принятых данных. Также удобно работать с указателями при работе с различными списками объектов, более крупных, чем просто переменная типа int

Указатели удобны при передаче в функцию объектов большого размера, чтобы не создавалась копия такого объекта, а также для возврата из функции более чем одного значения.
Леонид Иванович Администратор
  Отправлено: 14 Апреля, 2015 - 12:09:44
Post Id
Super Member  (866)
Откуда: Minsk
Репутация: 35

Где-то читал, что все люди делятся на две категории: которые понимают указатели Си, и которые не понимают. Я себя отношу ко второй категории. Поэтому использую указатели крайне редко. Вообще, их значимость для языка Си очень преувеличена, они лишь запутывают исходники и делают программы менее безопасными.

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

CODE:
void Menu_GetVStep(char *s1, char *s2)


При работе с буфером:

CODE:
static char *TxPtr; //указатель буфера передачи
...
char data = *TxPtr++; //чтение байта из буфера
...


Классический пример - вывод строки:

CODE:
void LCD_PutString(char __flash *s)
{
while(*s) LCD_PutChar(*s++);
}
Victor_P.
  Отправлено: 14 Апреля, 2015 - 12:23:36
Post Id
Junior Member  (67)
Откуда: Хорол, Україна
Репутация: 1

koyodza, Леонид Иванович, большое спасибо!
Теперь понятно. Куда попало их тыкать мало того, что безсмысленно, но и вредно.
А там, где он нужен, он сам напросится Улыбка
Но пока что я тоже в категории тех, кто их не понимает Радость , вернее не приходилось использовать в своем коде.

(Отредактировано автором: 14 Апреля, 2015 - 17:52:47)

limon
  Отправлено: 12 Августа, 2015 - 11:04:13
Post Id
Newbie  (45)
Репутация: 1

с указателями есть интересный примерчик

unsigned char TxField[512]; // приемный буфер, читаем из uart


struct RDM_Packet *rdm; //некая структура пакета принятого по uart

rdm = (struct RDM_Packet *)&TxField; // накладываем структуру на входной буфер

rdm->DestID[4]= 0xFF; // а тут самое интересное, работаем с элементами структуры
rdm->DestID[5]= 0xFF;
rdm->CmdCls = DISC_CMD;
rdm->PID = DISC_UNIQUE_BRANCH;

Есть еще UNION
классная вещь когда надо обратится по байтно и побитно к переменной
либо рассматривать рассматривать 4 байта как uint32_t либо как float kb как массив из 4-х uint8_t
пример не выложу нету под рукой

(Отредактировано автором: 12 Августа, 2015 - 11:19:59)

koyodza
  Отправлено: 12 Августа, 2015 - 12:46:56
Post Id
Advanced Member  (313)
Откуда: Kyiv
Репутация: 7

Выше я упоминал об этом ( указатели на структуры при разборе буфера принятых данных), хотя и не приводил пример кода. Но на некоторых платформах нужно помнить, что обращение к невыровненным данным может приводить к исключениям, в частности на многих старых ARM
Средствами языка С этого можно избежать, если определить структуру как packed
Битовые поля и UNION к указателям отношения не имеют. Кстати, сами битовые поля часто обрабатываются крайне неэффективно, тут нужно смотреть какое ядро и какой компилятор.

(Отредактировано автором: 12 Августа, 2015 - 12:48:17)

Буратино
  Отправлено: 04 Октября, 2015 - 19:36:18
Post Id
Newbie  (38)
Репутация: 0

"указатели на структуры при разборе буфера принятых данных"
Да, я тош в крайнем прожекте прочувствовал.. Такая прэлестьУлыбка
Victor_P.
  Отправлено: 02 Декабря, 2015 - 21:02:12
Post Id
Junior Member  (67)
Откуда: Хорол, Україна
Репутация: 1

Что значит сообщение компилятора
in expansion of macro 'BT_SEL'
в 2х строках этого кода:
CODE:

if (BT_SEL)
{
sei();
Beep(250);
DotDisp = 1;
ReCode(NumVer,3);
while (BT_SEL){};
DotDisp = 0;
cli();
SetSIStart = 1;
}

сам макрос
CODE:
#define BT_SEL PINC&(1<<PINC2) == 0 //кнопка select/ok
koyodza
  Отправлено: 02 Декабря, 2015 - 21:06:04
Post Id
Advanced Member  (313)
Откуда: Kyiv
Репутация: 7

А как определен PINC2 ?
Victor_P.
  Отправлено: 02 Декабря, 2015 - 21:12:32
Post Id
Junior Member  (67)
Откуда: Хорол, Україна
Репутация: 1

Вот кусок с iom168pa.h:
Цитата:

#define PINC _SFR_IO8(0x06)
#define PINC6 6
#define PINC5 5
#define PINC4 4
#define PINC3 3
#define PINC2 2
#define PINC1 1
#define PINC0 0

или имеется в виду направление вход/выход?
Вродь тоже нормально, вход с пуллапом
CODE:

// Port C initialization
// Function: Bit6=In Bit5=Out Bit4=Out Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC6) | (1<<DDC5) | (1<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit6=T Bit5=0 Bit4=0 Bit3=P Bit2=P Bit1=P Bit0=P
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (1<<PORTC3) | (1<<PORTC2) | (1<<PORTC1) | (1<<PORTC0);


P.S. на всякий случай уточню, что это именно сообщение, а не ошибка.

Upd
Заменил
CODE:
#define BT_SEL PINC&(1<<PINC2) == 0

на
CODE:
#define BT_SEL !(PINC&(1<<PINC2))

сообщение пропало

(Отредактировано автором: 02 Декабря, 2015 - 21:45:06)

koyodza
  Отправлено: 02 Декабря, 2015 - 22:51:16
Post Id
Advanced Member  (313)
Откуда: Kyiv
Репутация: 7

Вероятно это предупреждение о неявном преобразовании типов: (1<<PINC2) имеет разрядность int по-умолчанию (для IAR AVR это 16 бит), а PINC определен скорее всего как volatile unsigned char или подобным образом, т.е. 8 бит
БывшийБрат
  Отправлено: 08 Января, 2016 - 20:42:10
Post Id
Newbie  (1)
Репутация: 0

Приоритео == выше чем приоритет логического И. Так что скобочки, скобочки...
Victor_P.
  Отправлено: 08 Января, 2016 - 22:40:42
Post Id
Junior Member  (67)
Откуда: Хорол, Україна
Репутация: 1

Таки да, скобочки, попробовал с ними, все норм.
Сейчас уже не актуально, но на будущее пригодится.

Upd. 20.02.2016
Есть вопрос по функциям
CODE:
void eeprom_write_word (uint16_t *__p, uint16_t __value);
void eeprom_update_word (uint16_t *__p, uint16_t __value);

Эти функции блокируют прерывания при записи, или их нужно окружать cli(); и sei();?

(Отредактировано автором: 20 Февраля, 2016 - 11:40:16)

Страниц (1): [1]
Сейчас эту тему просматривают: 1 (гостей: 1, зарегистрированных: 0)
« Программирование »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 




Powered by ExBB
ExBB FM 1.0 RC1 by TvoyWeb.ru
UaExBB Style

[Script Execution time: 0.1318]     [ Gzip Disabled ]