реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Использование глобальных переменных
demiurg1978
сообщение Jan 11 2017, 08:56
Сообщение #16


Местный
***

Группа: Участник
Сообщений: 320
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Хм... Всем спасибо. Некоторым - в который уже раз... sm.gif
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jan 11 2017, 09:50
Сообщение #17


Знающий
****

Группа: Свой
Сообщений: 569
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Сергей Борщ @ Jan 10 2017, 10:33) *
Собрать все параметры в структуру (наверняка это уже сделано для удобства сохранения/чтения да и вообще для повышения читабельности кода). Передавать в редактор указатель на эту структуру. Можно создавать копию этой структуры, передавать в редактор указатель на копию и переписывать обратно из копии в основную структуру только после того, как пользователь подтвердит, что он действительно в своем уме.


Тоже хотел квакнуть, но это уже сделали.
Это промежуточный вариант к ООП. Каждый модуль как-бы "псевдо-клас" со своими данными в виде струкутуры, которая extern и видна глобально через
1 указатель. Позволяет сильно сэкономить на написании "extern".
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 11 2017, 11:31
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(k155la3 @ Jan 11 2017, 11:50) *
Позволяет сильно сэкономить на написании "extern".

И не только. В большинстве случаев это помогает оптимизации, поскольку все данные с которыми работает этот программный модуль находятся гарантированно рядом, что подвигает компилятор на короткие индексные адресации. Кроме того, такие структуры данных можно паковать, если начнет место поджимать.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 11 2017, 12:52
Сообщение #19


Гуру
******

Группа: Модераторы
Сообщений: 7 987
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (demiurg1978 @ Jan 10 2017, 13:24) *
Народ, не поделитесь примерами?

примерно так:
CODE
bool cfg_editor::do_edit(bool from_last)
{
    // return true to edit field
    auto always            = [](cfg_cache &)     { return true; };
    auto dhcp_disabled     = [](cfg_cache & cfg) { return cfg->Localhost.DHCP_enabled == false; };


    struct
    {
        bool (*is_item_active)(cfg_cache &);
        cfg_editor_ui::result (*function)(cfg_editor *);
    } const Table[] =
    {
    #define HANDLER(edit_func, param_name, ...)  [](cfg_editor * editor) { return editor-> edit_func (param_name , editor->Cfg-> __VA_ARGS__); }
        { always,         HANDLER(edit_MAC,       "MAC address    ",                          Localhost.MAC_address) },
        { always,         HANDLER(choose_YN,      "DHCP enabled "  ,                          Localhost.DHCP_enabled) },
        { dhcp_disabled,  HANDLER(edit_IP,        "IP address     ",                          Localhost.IP_address.addr) },
        { dhcp_disabled,  HANDLER(edit_IP,        "Netmask        ",                          Localhost.Netmask.addr) },
        { dhcp_disabled,  HANDLER(edit_IP,        "Gateway        ",                          Localhost.Gateway.addr) },
#if LWIP_DNS
        { dhcp_enabled,   HANDLER(edit_IP,        "DNS1           ",                          Localhost.DNS[0].addr) },
        { dhcp_enabled,   HANDLER(edit_IP,        "DNS2           ",                          Localhost.DNS[1].addr) },
#endif
        { always,         HANDLER(edit,           "Hostname       ",                          Localhost.Hostname) },

        { always,         HANDLER(edit,           "Telnet port    ",                          Telnet.Port) },
        { always,         HANDLER(edit_password,  "Telnet password (space = disabled)",       Telnet.Password) },

        { always,         HANDLER(edit,           "Serial port baudrate   ",          Serial.Baudrate, 600, 115200) },
        .........
    };

    size_t const Last_index = sizeof(Table) / sizeof(Table[0]) - 1;
    size_t Index = from_last ? Last_index : 0;

    for(;;)
    {
        Console.new_line();
    Repeat:
        switch(Table[Index].function(this))
        {
        case result::CONSOLE_CLOSED:
        case result::TIMEOUT:
            return false;

        case result::ABORTED:
            return true;

        case result::KEY_UP:
            if(Index == 0)
            {
                Console.send('\r');
                goto Repeat;
            }
            while(--Index && !Table[Index].is_item_active(Cfg))
               ;
            break;

        case result::JUST_ENTER:
        case result::OK:
            if(Index == Last_index)
                return true;
            while(++Index < Last_index && !Table[Index].is_item_active(Cfg))
               ;

            if(!Table[Index].is_item_active(Cfg))   // if last item inactive
                return true;
            break;

        case result::KEY_DOWN:
            if(Index == Last_index)
            {
                Console.send('\r');
                goto Repeat;
            }
            while(++Index < Last_index && !Table[Index].is_item_active(Cfg))
               ;
            // last index inactive, go back to active
            if(Index == Last_index && !Table[Index].is_item_active(Cfg))
            {
                while(--Index && !Table[Index].is_item_active(Cfg))
                   ;
                Console.send('\r');
                goto Repeat;

            }
            break;
        }
    }
    return true;    // make eclipse parser happy
}



--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Jan 11 2017, 13:25
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 763
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(Сергей Борщ @ Jan 11 2017, 15:52) *
примерно так:
struct
{
bool (*is_item_active)(cfg_cache &);
cfg_editor_ui::result (*function)(cfg_editor *);
} const Table[]


Таблица const, но не static - живет на стеке и заполняется при каждом входе в функцию sm.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 12 2017, 10:05
Сообщение #21


Гуру
******

Группа: Модераторы
Сообщений: 7 987
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Непомнящий Евгений @ Jan 11 2017, 15:25) *
Таблица const, но не static - живет на стеке и заполняется при каждом входе в функцию sm.gif
Оп-па! Правда со static оно тоже в ОЗУ (до стандарта C++17 лямбды не являются constexpr), но уже не на стеке. Спасибо, упустил.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
aiwa
сообщение Jan 12 2017, 12:39
Сообщение #22


Местный
***

Группа: Участник
Сообщений: 238
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(scifi @ Jan 11 2017, 10:31) *
Неправда. static позволяет не засорять глобальное пространство имён. Скажем, если в программе два десятка модулей, и в каждом - десяток своих переменных, то это уже 200 глобальных переменных. Кому нужен этот бардак?

Ну бардак все-таки не хаос. Переменные видимы в определенном порядке и избыточное количество не критично: пусть лучше уж валяется в глобальном списке, чем тратить на нее семиразовое нажатие клавиш. И реальная необходимость возникла не из-за "засорять", а именно "спрятать" от второго. Но это уже флейм, ибо Вы обрезали главное: один программист - сам себе хозяин. И перевод из static в глобальную особого значения не имеет: насколько я понимаю имелись ввиду переменные static исключительно внутри функции.
Но чтобы следовать упомянутому ТС принципу "использование глобальных переменных нужно максимально минимизировать" перевода из static в глобальные недостаточно, нужно перевести эту переменную в параметры. Этот принцип никак не регламентирует количество глобальных переменных.

Было:
void func()
{
static int value =0;
//
модифицирующий код value;
}

Стало:
int value =0;

void func(int* value)
{
//
модифицирующий код value;
}







Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 14 2017, 10:53
Сообщение #23


Гуру
******

Группа: Модераторы
Сообщений: 7 987
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (aiwa @ Jan 12 2017, 14:39) *
Переменные видимы в определенном порядке и избыточное количество не критично: пусть лучше уж валяется в глобальном списке, чем тратить на нее семиразовое нажатие клавиш. И реальная необходимость возникла не из-за "засорять", а именно "спрятать" от второго. Но это уже флейм, ибо Вы обрезали главное: один программист - сам себе хозяин. И перевод из static в глобальную особого значения не имеет
Из соседней ветки:
QUOTE (Mister_DSP @ Jan 13 2017, 08:13) *
Создаю библиотеку (lib) в Keil по исходникам из множества файлов.
Затем получившуюся библиотеку пристыковываю к другому проекту (главному).

При линковке выдаёт ошибку: найдены одинаковые имена в libfile.o и module.o

Исходные тексты программ не моего авторства, около 100 имён совпадает, так что переименовывать не вариант.


Попробуйте убедить его, что он сам себе хозяин и static значения не имеет wink.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 14 2017, 16:29
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 670
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Сергей Борщ @ Jan 11 2017, 15:52) *
примерно так:

У этого автора не так все легко с абстракциями, вряд ли вы ему помогли.

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

Код
#define    HALLS_CHANNELS_QTY    2

typedef struct
{    int             position;
    unsigned char    cur;                //current_inputs;
    unsigned char    prev;            //previous_inputs
    unsigned char    prev_prev;        //before previous inputs
    unsigned char    init;
}    hall_type;

extern hall_type hall[HALLS_CHANNELS_QTY];
extern hall_type old_hall[HALLS_CHANNELS_QTY];


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Укушенный воблой
сообщение Jan 14 2017, 18:03
Сообщение #25


Частый гость
**

Группа: Участник
Сообщений: 197
Регистрация: 8-07-16
Пользователь №: 92 484



Цитата(demiurg1978 @ Jan 9 2017, 19:26) *
Хочу узнать мнение насчет использования глобальных переменных. Спрашиваю вот почему: неоднократно слышал, что использование глобальных переменных нужно максимально минимизировать. Откуда пошло это? В данный момент пишу проект. Свои проекты всегда стараюсь разделить на модули. static переменные. использование в других модулях посредством set_value (); get_value ();. Но в нынешнем проекте у меня много параметров. И если честно, я заколебался на каждую переменную писать свои функции установки и получения переменных. Хочу вывести переменные из static в глобальные.
Ваши за и против.

Не один из принципов нельзя возводить в абсолют.
Если нельзя, но очень хочется и это сильно упрощает жизнь - то можно.
Вон про GOTO тоже написано, что "правильные пасаны" GoTO не используют.
А тем не менее ИМЕННО GOTO в ряде случаев упрощает код и делает его более читабельным
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Jan 16 2017, 05:14
Сообщение #26


Знающий
****

Группа: Свой
Сообщений: 763
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(aiwa @ Jan 12 2017, 15:39) *
Ну бардак все-таки не хаос. Переменные видимы в определенном порядке и избыточное количество не критично: пусть лучше уж валяется в глобальном списке, чем тратить на нее семиразовое нажатие клавиш.


У вас очень трепетное отношение к нажатию клавиш sm.gif Опять же, имена глобальных переменных обычно должны быть длинными и осмысленными, часто это больше 7 символов wink.gif
Go to the top of the page
 
+Quote Post
aiwa
сообщение Jan 16 2017, 08:26
Сообщение #27


Местный
***

Группа: Участник
Сообщений: 238
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(Сергей Борщ @ Jan 14 2017, 12:53) *
Попробуйте убедить его, что он сам себе хозяин и static значения не имеет wink.gif

Как раз в приведенном примере из соседней ветки static значения не имеет:
static имеет целью сделать переменную недоступной извне, что совершенно не подходит топикстартеру.
Там конфликт имен в чистом виде.

Цитата(Непомнящий Евгений @ Jan 16 2017, 07:14) *
У вас очень трепетное отношение к нажатию клавиш sm.gif Опять же, имена глобальных переменных обычно должны быть длинными и осмысленными, часто это больше 7 символов wink.gif

7-кратное нажатие - это написание "static"+пробел перед глобальными переменными, которые желательно сделать недоступными вне файла.
В случае "сам себе хозяин" без них можно обойтись.

Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Jan 16 2017, 10:14
Сообщение #28


Знающий
****

Группа: Свой
Сообщений: 763
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(aiwa @ Jan 16 2017, 11:26) *
7-кратное нажатие - это написание "static"+пробел перед глобальными переменными, которые желательно сделать недоступными вне файла.
В случае "сам себе хозяин" без них можно обойтись.


Я как раз про нажатия и говорю. Глобальная переменная - это тип, название и комментарий, причем название должно быть достаточно длинным. Т.е. несколько десятков символов точно. На этом фоне экономия 7 символов - это ни о чем. Можно конечно давать имена вроде xz42 и комментарии не писать maniac.gif

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

Поэтому рекомендация не использовать static из-за затрат на его написание смотрится странновато sm.gif Но если экономить символы, то ничто не мешает написать #define S static - это минус 5 нажатий wink.gif
Go to the top of the page
 
+Quote Post
aiwa
сообщение Jan 17 2017, 02:54
Сообщение #29


Местный
***

Группа: Участник
Сообщений: 238
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(Непомнящий Евгений @ Jan 16 2017, 12:14) *
Поэтому рекомендация не использовать static из-за затрат на его написание смотрится странновато sm.gif


Как раз ровно наоборот: я одобряю решение топикстартера затратить лишние нажатия клавиш на удаление уже написанного static.
Что бы не писать для доступа к переменным функции-обертки (или макросы). Для единоличника считаю это допустимым и вполне разумным.
С небольшой поправкой: для переменных, которые могут изменить свою структуру в будущем, не полениться и написать доступ через обертки.


Цитата(Непомнящий Евгений @ Jan 16 2017, 12:14) *
Но если экономить символы, то ничто не мешает написать #define S static - это минус 5 нажатий wink.gif

Не, такой хоккей нам не нужен.
Конечно, это дело личных предпочтений, но как по мне "S" вместо static смотрится еще хуже переменной xz42.
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st August 2017 - 00:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.25429 секунд с 7
ELECTRONIX ©2004-2016