demiurg1978 1 9 января, 2017 Опубликовано 9 января, 2017 (изменено) · Жалоба Хочу узнать мнение насчет использования глобальных переменных. Спрашиваю вот почему: неоднократно слышал, что использование глобальных переменных нужно максимально минимизировать. Откуда пошло это? В данный момент пишу проект. Свои проекты всегда стараюсь разделить на модули. static переменные. использование в других модулях посредством set_value (); get_value ();. Но в нынешнем проекте у меня много параметров. И если честно, я заколебался на каждую переменную писать свои функции установки и получения переменных. Хочу вывести переменные из static в глобальные. Ваши за и против. Изменено 9 января, 2017 пользователем demiurg1978 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 9 января, 2017 Опубликовано 9 января, 2017 · Жалоба неоднократно слышал, что.. Ну так и спрашиваете там, где "неоднократно слышали". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
desh 0 9 января, 2017 Опубликовано 9 января, 2017 · Жалоба Хочу вывести переменные из static в глобальные. Ваши за и против. Плохая практика. Программа быстро превращается в это Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 9 января, 2017 Опубликовано 9 января, 2017 · Жалоба ... Скажу честно, с английским настолько не дружу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 9 января, 2017 Опубликовано 9 января, 2017 · Жалоба Плохая практика. К чему эти глупые страшилки не по делу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 10 января, 2017 Опубликовано 10 января, 2017 (изменено) · Жалоба Хочу вывести переменные из static в глобальные. Ваши за и против. В Вашем случае, когда Вы сам себе хозяин это не имеет никакого значения, кроме личных предпочтений. Само ключевое слово static появилось, при появлении второго программиста. Первый не хотел, чтобы другой использовал его глобальные переменные, вот и прятал их посредством статика. Что касается функций установки и чтения значений переменных, то у меня такая же история: терпения на их написание не хватает и я обычно в приватную секцию вставляю "public:". Но даже в этом случае для тех переменных, тип или значения которых могут измениться в будущем, функции (или псевдофункции) прописываю сразу. Изменено 10 января, 2017 пользователем aiwa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DimaG 0 10 января, 2017 Опубликовано 10 января, 2017 · Жалоба static переменные. использование в других модулях посредством set_value (); get_value ();. Но в нынешнем проекте у меня много параметров. И если честно, я заколебался на каждую переменную писать свои функции установки и получения переменных. Смысла в простых get/set функциях, тупо устанавливающих значения локальных переменных нет. Проще использовать глобальные переменные. get/set функции нужны в том случае, если производится какая-то дополнительная работа, помимо установки/возврата переменной. Например int set_age(int age) { if (age>=0 && age <=100) { local_age = age; return 0; } perror("incorrect age!"); return -1; } К вопросу о "много параметров", может есть смысл объединить их в структуры? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 10 января, 2017 Опубликовано 10 января, 2017 · Жалоба Хочу узнать мнение насчет использования глобальных переменных. Спрашиваю вот почему: неоднократно слышал, что использование глобальных переменных нужно максимально минимизировать. Откуда пошло это? В данный момент пишу проект. Свои проекты всегда стараюсь разделить на модули. static переменные. использование в других модулях посредством set_value (); get_value ();. Но в нынешнем проекте у меня много параметров. И если честно, я заколебался на каждую переменную писать свои функции установки и получения переменных. Хочу вывести переменные из static в глобальные. Ваши за и против. Проблема в связности. Если у вас все модули знают все про все другие модули - то связность высокая. Сложно понять, кто именно меняет данную переменную и по каким позывам. Сложно поменять алгоритм работы какого-то одного модуля - при этом придется менять все другие. Часто нельзя просто взять и записать в переменную значение - иногда это можно сделать только в определенных состояниях, иногда такая запись должна быть защищена критической секцией, иногда нужно проверить значение или выполнить какие-то действия до/после записи. Если все это размазать по разным модулям - очень легко где-то что-то забыть. Просто механически каждую переменную оборачивать в пару функций смысла нет. Но если модулю 1 нужны прям вот все переменные модуля 2, то у вас что-то не так с разделением на модули. Обычно модуль дает какой-то интерфейс, куда входят функции, и, возможно, какой-то набор глобальных переменных. Опять же, вот пусть у нас есть модуль "передатчик по порту". Если у нас появятся два порта и понадобятся два передатчика - как мы будем выкручиваться? Поэтому обычно тут так или иначе используют ООП - все переменные, которые требуются "передатчику" собираются в структуру, а каждая функция получает указатель на эту структуру (или к примеру числовой дескриптор). А вообще, дайте конкретный пример :) По нему уже можно дать какие-то рекомендации К чему эти глупые страшилки не по делу. Это не то, чтобы страшилки. Обычно, если в коде много GOTO или функции на тысячи строк или все "потроха" торчат наружу, то с ним что-то не так :) Хотя конечно возможны какие-то ситуации, когда все это оправдано Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 10 января, 2017 Опубликовано 10 января, 2017 · Жалоба А вообще, дайте конкретный пример :) По нему уже можно дать какие-то рекомендации Редактирование параметров в меню. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 136 10 января, 2017 Опубликовано 10 января, 2017 · Жалоба Редактирование параметров в меню.Собрать все параметры в структуру (наверняка это уже сделано для удобства сохранения/чтения да и вообще для повышения читабельности кода). Передавать в редактор указатель на эту структуру. Можно создавать копию этой структуры, передавать в редактор указатель на копию и переписывать обратно из копии в основную структуру только после того, как пользователь подтвердит, что он действительно в своем уме. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 10 января, 2017 Опубликовано 10 января, 2017 · Жалоба Редактирование параметров в меню. Можно сделать так, как выше предложил Сергей. У меня обычно параметры редактируются не только в меню, но и по интерфейсу (причем протоколы могут быть разные). Кроме того, на разных устройствах разные способы организации меню (разные дисплеи, где-то семисегментное табло). Поэтому у меня каждый параметр завернут в функцию доступа (для упрощения сделан мини-язык на макросах) и затем параметры всех модулей добавляются в общий массив (код параметра + функция доступа). Функция доступа получает специальный поток (откуда читается или куда пишется значение, значение может быть разных типов, а некоторые параметры имеют несколько значений) и требуемое действие (прочитать / записать / проверить допустимость значения). Возвращает успех или код ошибки. И далее уже имея такой массив, несложно организовать редактирование / отображение параметров через меню или по интерфейсу. Можно сделать перебор всех параметров, их сохранение в какой-то промежуточный формат и т.п. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 10 января, 2017 Опубликовано 10 января, 2017 (изменено) · Жалоба ... Спасибо всем за ответы.Народ, не поделитесь примерами? Я всегда старался посматривать, как делают другие. Брать лучшее из примеров. Не постесняюсь сказать, что многому научился как раз на форумах. На ответах на мои вопросы и приведенных примерах. Изменено 10 января, 2017 пользователем demiurg1978 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 11 января, 2017 Опубликовано 11 января, 2017 · Жалоба Спасибо всем за ответы.Народ, не поделитесь примерами? Я всегда старался посматривать, как делают другие. Брать лучшее из примеров. Не постесняюсь сказать, что многому научился как раз на форумах. На ответах на мои вопросы и приведенных примерах. Готовый код я дать не могу - он писался для дяди, на плюсах и довольно запутан. Основная мысль, если переложить ее на Си, выглядит так Интерфейс 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, доступ к произвольному параметру через меню, выплевывание всех параметров по интерфейсу и т.п. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 11 января, 2017 Опубликовано 11 января, 2017 · Жалоба Использование // получить значение параметра 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" ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 11 января, 2017 Опубликовано 11 января, 2017 · Жалоба Само ключевое слово static появилось, при появлении второго программиста. Первый не хотел, чтобы другой использовал его глобальные переменные, вот и прятал их посредством статика. Неправда. static позволяет не засорять глобальное пространство имён. Скажем, если в программе два десятка модулей, и в каждом - десяток своих переменных, то это уже 200 глобальных переменных. Кому нужен этот бардак? В си разве возможна такая запись: ".type" ? Погуглите на тему "что нового в C99 по сравнению с C90". Там немало приятных плюшек добавилось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться