|
Использование глобальных переменных |
|
|
|
 |
Ответов
|
Jan 10 2017, 06:30
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(demiurg1978 @ Jan 9 2017, 21:26)  Хочу узнать мнение насчет использования глобальных переменных. Спрашиваю вот почему: неоднократно слышал, что использование глобальных переменных нужно максимально минимизировать. Откуда пошло это? В данный момент пишу проект. Свои проекты всегда стараюсь разделить на модули. static переменные. использование в других модулях посредством set_value (); get_value ();. Но в нынешнем проекте у меня много параметров. И если честно, я заколебался на каждую переменную писать свои функции установки и получения переменных. Хочу вывести переменные из static в глобальные. Ваши за и против. Проблема в связности. Если у вас все модули знают все про все другие модули - то связность высокая. Сложно понять, кто именно меняет данную переменную и по каким позывам. Сложно поменять алгоритм работы какого-то одного модуля - при этом придется менять все другие. Часто нельзя просто взять и записать в переменную значение - иногда это можно сделать только в определенных состояниях, иногда такая запись должна быть защищена критической секцией, иногда нужно проверить значение или выполнить какие-то действия до/после записи. Если все это размазать по разным модулям - очень легко где-то что-то забыть. Просто механически каждую переменную оборачивать в пару функций смысла нет. Но если модулю 1 нужны прям вот все переменные модуля 2, то у вас что-то не так с разделением на модули. Обычно модуль дает какой-то интерфейс, куда входят функции, и, возможно, какой-то набор глобальных переменных. Опять же, вот пусть у нас есть модуль "передатчик по порту". Если у нас появятся два порта и понадобятся два передатчика - как мы будем выкручиваться? Поэтому обычно тут так или иначе используют ООП - все переменные, которые требуются "передатчику" собираются в структуру, а каждая функция получает указатель на эту структуру (или к примеру числовой дескриптор). А вообще, дайте конкретный пример  По нему уже можно дать какие-то рекомендации Цитата(zltigo @ Jan 9 2017, 23:57)  К чему эти глупые страшилки не по делу. Это не то, чтобы страшилки. Обычно, если в коде много GOTO или функции на тысячи строк или все "потроха" торчат наружу, то с ним что-то не так  Хотя конечно возможны какие-то ситуации, когда все это оправдано
|
|
|
|
|
Jan 10 2017, 07:11
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(Непомнящий Евгений @ Jan 10 2017, 12:30)  А вообще, дайте конкретный пример  По нему уже можно дать какие-то рекомендации Редактирование параметров в меню.
|
|
|
|
|
Jan 10 2017, 08:17
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(demiurg1978 @ Jan 10 2017, 10:11)  Редактирование параметров в меню. Можно сделать так, как выше предложил Сергей. У меня обычно параметры редактируются не только в меню, но и по интерфейсу (причем протоколы могут быть разные). Кроме того, на разных устройствах разные способы организации меню (разные дисплеи, где-то семисегментное табло). Поэтому у меня каждый параметр завернут в функцию доступа (для упрощения сделан мини-язык на макросах) и затем параметры всех модулей добавляются в общий массив (код параметра + функция доступа). Функция доступа получает специальный поток (откуда читается или куда пишется значение, значение может быть разных типов, а некоторые параметры имеют несколько значений) и требуемое действие (прочитать / записать / проверить допустимость значения). Возвращает успех или код ошибки. И далее уже имея такой массив, несложно организовать редактирование / отображение параметров через меню или по интерфейсу. Можно сделать перебор всех параметров, их сохранение в какой-то промежуточный формат и т.п.
|
|
|
|
|
Jan 10 2017, 11:24
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(Непомнящий Евгений @ Jan 10 2017, 14:17)  ... Спасибо всем за ответы.Народ, не поделитесь примерами? Я всегда старался посматривать, как делают другие. Брать лучшее из примеров. Не постесняюсь сказать, что многому научился как раз на форумах. На ответах на мои вопросы и приведенных примерах.
Сообщение отредактировал demiurg1978 - Jan 10 2017, 11:26
|
|
|
|
|
Jan 11 2017, 06:05
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(demiurg1978 @ Jan 10 2017, 14:24)  Спасибо всем за ответы.Народ, не поделитесь примерами? Я всегда старался посматривать, как делают другие. Брать лучшее из примеров. Не постесняюсь сказать, что многому научился как раз на форумах. На ответах на мои вопросы и приведенных примерах. Готовый код я дать не могу - он писался для дяди, на плюсах и довольно запутан. Основная мысль, если переложить ее на Си, выглядит так ИнтерфейсCODE
enum ParamType { paramInt, paramUint, paramFloat, paramBytes, };
// Поток для чтения и записи значений // В простейшем случае это просто буфер, размер и тип значения в буфере // Если параметр может иметь несколько значений, то придется усложнить (скажем сделать односвязный список таких структур) // Если хочется иметь возможность делать произвольные действия (писать/читать сразу в формате протокола и т.п.), то тут должны быть указатели на функции struct ParamStream { void *buf; uint16_t size; ParamType type; bool error; // произошла ошибка чтения/записи? };
// это интерфейс к ParamStream, который позволяет читать/писать значение // конкретная реализация зависит от вида ParamStream uint8_t paramStream_readUI8(ParamStream *s) { // конвертирует содержимое потока в uint8_t; если это невозможно - устанавливает s->error } uint16_t paramStream_readUI16(ParamStream *s); ... uint16_t paramStream_readBytes(ParamStream *s, byte *buf, byte bufSize);
void paramStream_writeUI8(ParamStream *s, uint8_t v); ... void paramStream_writeBytes(ParamStream *s, const byte *buf, byte bufSize);
enum ParamResult { parres_OK, parres_BadValue, parres_NoParam, parres_NoAction, ... };
enum ParamAction { paract_Get, paract_Set, paract_Check, // проверить значение на допустимость без установки - бывает полезно в меню };
typedef ParamResult (*ParamAccessor)(ParamStream *s, ParamAction act);
struct ParamInfo { uint16_t code; ParamAccessor accessor; };
/// Эта функция для пользователей данной системы. Она ищет в глобальном массиве ParamInfo параметр с данным кодом (бинарный поиск к примеру) и вызывает его accessor ParamResult paramAccessor(uint16_t code, ParamStream *s, ParamAction act);
ИспользованиеКод // получить значение параметра 42 unsigned value; ParamStream stream = {.buf=&value, .size = sizeof(value), .type=paramUint}; paramAccessor(42, &stream, paract_Get);
// установить значение параметра 55 byte buf[10] = {1, 2, 3}; ParamStream stream = {.buf=&buf, .size = sizeof(buf), .type=paramBytes}; paramAccessor(55, &stream, paract_Set); Модуль 1Код int a, b;
// вычисляемый параметр только для чтения ParamResult param_42(ParamStream *s, ParamAction act) { switch(act) { case paract_Get: paramStream_writeUI8(s, a+b); return parres_OK; default: return parres_NoAction; } } Модуль 2Код byte buf[20];
// чтение/запись ParamResult param_55(ParamStream *s, ParamAction act) { switch(act) { case paract_Get: paramStream_writeBytes(s, buf, 20); return parres_OK; case paract_Set: paramStream_readBytes(s, buf, 20); return parres_OK; default: return parres_NoAction; } } Где-то нужен файл, который все функции доступа поместит в один массив (и в этот файл надо включить хидеры всех модулей с параметрами). Код ParamInfo paramInfo[] = { {42, param_42}, {55, param_55}, {0, 0} // терминатор Теперь у нас есть обобщенный механизм доступа к параметру любого типа по коду. Дальше все в наших руках - можно написать адаптер для modbus / etc, доступ к произвольному параметру через меню, выплевывание всех параметров по интерфейсу и т.п.
|
|
|
|
|
Jan 11 2017, 08:25
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(Непомнящий Евгений @ Jan 11 2017, 12:05)  ИспользованиеКод // получить значение параметра 42 unsigned value; ParamStream stream = {.buf=&value, .size = sizeof(value), .type=paramUint}; paramAccessor(42, &stream, paract_Get);
// установить значение параметра 55 byte buf[10] = {1, 2, 3}; ParamStream stream = {.buf=&buf, .size = sizeof(buf), .type=paramBytes}; paramAccessor(55, &stream, paract_Set); В си разве возможна такая запись: ".type" ?
|
|
|
|
Сообщений в этой теме
demiurg1978 Использование глобальных переменных Jan 9 2017, 18:26 zltigo Цитата(demiurg1978 @ Jan 9 2017, 20:26) н... Jan 9 2017, 19:22 desh Цитата(demiurg1978 @ Jan 9 2017, 21:26) Х... Jan 9 2017, 20:28 demiurg1978 Цитата(desh @ Jan 10 2017, 02:28) ...
Ска... Jan 9 2017, 20:33 zltigo Цитата(desh @ Jan 9 2017, 22:28) Плохая п... Jan 9 2017, 20:57 aiwa Цитата(demiurg1978 @ Jan 9 2017, 20:26) Х... Jan 10 2017, 01:59 Dima_G Цитата(demiurg1978 @ Jan 10 2017, 01:26) ... Jan 10 2017, 03:18  Сергей Борщ QUOTE (demiurg1978 @ Jan 10 2017, 09:11) ... Jan 10 2017, 07:33   k155la3 Цитата(Сергей Борщ @ Jan 10 2017, 10:33) ... Jan 11 2017, 09:50    zltigo Цитата(k155la3 @ Jan 11 2017, 11:50) Позв... Jan 11 2017, 11:31    Сергей Борщ QUOTE (demiurg1978 @ Jan 10 2017, 13:24) ... Jan 11 2017, 12:52     Непомнящий Евгений Цитата(Сергей Борщ @ Jan 11 2017, 15:52) ... Jan 11 2017, 13:25      Сергей Борщ QUOTE (Непомнящий Евгений @ Jan 11 2017, 15... Jan 12 2017, 10:05     Dog Pawlowa Цитата(Сергей Борщ @ Jan 11 2017, 15:52) ... Jan 14 2017, 16:29 scifi Цитата(aiwa @ Jan 10 2017, 04:59) Само кл... Jan 11 2017, 08:31 demiurg1978 Хм... Всем спасибо. Некоторым - в который уже раз.... Jan 11 2017, 08:56 aiwa Цитата(scifi @ Jan 11 2017, 10:31) Неправ... Jan 12 2017, 12:39 Сергей Борщ QUOTE (aiwa @ Jan 12 2017, 14:39) Перемен... Jan 14 2017, 10:53 Непомнящий Евгений Цитата(aiwa @ Jan 12 2017, 15:39) Ну бард... Jan 16 2017, 05:14 Укушенный воблой Цитата(demiurg1978 @ Jan 9 2017, 19:26) Х... Jan 14 2017, 18:03 aiwa Цитата(Сергей Борщ @ Jan 14 2017, 12:53) ... Jan 16 2017, 08:26 Непомнящий Евгений Цитата(aiwa @ Jan 16 2017, 11:26) 7-кратн... Jan 16 2017, 10:14 aiwa Цитата(Непомнящий Евгений @ Jan 16 2017, 12... Jan 17 2017, 02:54
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|