Перейти к содержанию
    

Немного стандарта написания программ на С

1. именно этим и плохо. Разово нужная переменная постоянно занимает память.

2. программы с глобальными переменными очень плохо читаются (ну это мое субъективное мнение)

3. глобальная - доступна всем желающим (во всей программе, либо в единице трансляции, если это - статик). Можно посадить трудноуловимые баги :).

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

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

 

Есть много нюансов о которых надо помнить при решении глобал-локал. Читаемость в общем случае будет в ущерб производительности, все зависит от того, насколько она вам критична.

Изменено пользователем ar__systems

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно пользоваться указателями

например вот так:

typedef struct {
  alt_buttons* buttons;                                             //ссылка на массив кнопок
  unsigned char max_key_num;                                //число кнопок в клавиатуре
  .......
  unsigned char alpha;                                             //прозрачность клавиатуры
} alt_keyboard;


void* h_VarA;


void Proc1(void)
{
  h_VarA->alpha = 123;   
}


main()
{
  alt_keyboard keyboard;

  system_init (&keyboard);

  h_VarA = (void*)&keyboard;

  Proc1();
}

Но в этом случае надо следить за указателем. Чтоб к нему не было обращений, когда он еще не инициализирован или динамическая структура уже освобождена

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно пользоваться указателями
Можно, но какой смысл? Заводим локальную переменную в main() и через указатель делаем ее как-бы глобальной. Какие преимущества это дает по сравнению с обычной глобальной переменной? Т.е. ради чего занимается лишняя память под указатель и ради чего мы вынуждаем процессор постоянно обращаться к структуре косвенно?

например вот так:
Вот так делать не нужно ни в коем случае. Вместо того, чтобы завести указатель на нужный тип и позволить компилятору контролировать ваши описки, вы заводите указатель на void * и вынуждены при каждом обращении вручную, принудительно приводить его к нужному типу. Компилятор не имеет возможности проверить, совместим ли объект, на который указывает указатель и тот тип, к которому вы его приводите методом грубой силы.

void Proc1(void)
{
  h_VarA->alpha = 123;   
}

Не скомпилится. h_VarA - указатель на void

  h_VarA = (void*)&keyboard;

Явное приведение лишнее. Любой не-cv (const и/или volatile) указатель приводится к void * неявно.

 

P.S. используйте кнопку rte-code-button.png на форме ввода для оформления кода.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно, но какой смысл? Заводим локальную переменную в main() и через указатель делаем ее как-бы глобальной. Какие преимущества это дает по сравнению с обычной глобальной переменной? Т.е. ради чего занимается лишняя память под указатель и ради чего мы вынуждаем процессор постоянно обращаться к структуре косвенно?

Смысла ни какого. И так делать не надо. Просто если очень хочется... Глобальной она все равно не будет, т.к. эта переменная уничтожится при выходе из функции (если рассматриваем вариант не с функцией main). Вообще, для этих целей есть операторы new и delete. Которые позволяют контролировать выделяемые ресурсы в момент работы программы.

Правильно будет так:

 

typedef struct {
alt_buttons* buttons; //ссылка на массив кнопок
unsigned char max_key_num; //число кнопок в клавиатуре
.......
unsigned char alpha; //прозрачность клавиатуры
} alt_keyboard;


keyboard* h_VarA;

main()
{
// Выделяем ресурсы
  h_VarA = new alt_keyboard;

// Работаем с выделенными ресурсами....

// Освобождаем ресурсы
  delete h_VarA;

// Работаем дальше...

}

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще, для этих целей есть операторы new и delete. Которые позволяют контролировать выделяемые ресурсы в момент работы программы.

Если мне не изменяет склероз, то операторы динамического распределения памяти new и delete отсутствуют в С и есть только в С++ , а топик вроде был как о С :)

alekseykoj, а для каких Вы PIC-контроллеров пишете на С++? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Извиняюсь :blush: А так?

 

typedef struct {
alt_buttons* buttons; //ссылка на массив кнопок
unsigned char max_key_num; //число кнопок в клавиатуре
.......
unsigned char alpha; //прозрачность клавиатуры
} alt_keyboard;


alt_keyboard* h_VarA;

main()
{
// Выделяем ресурсы
  h_VarA = malloc(sizeof(alt_keyboard));

// Работаем с выделенными ресурсами....

// Освобождаем ресурсы
  free(h_VarA);

// Работаем дальше...

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Я хочу сделать переменную глобальной, чтобы для нее весь проект был "прозрачен", чтобы из нескольких различных подпрограмм к ней был доступ. А переменная для работы с клавиатурой (что следует из ее названия) не должна быть динамически созданной/удаленной...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну и делай ее глобальной. Ни каких "противопоказаний" нет. Единственное "противопоказание" следить за корректностью значения в переменной. (она же глобальная... Может быть изменена из нескольких модулей программы). Необходимо оформлять программу таким образом чтоб другие модули получали значение переменной или изменяли его с помощью функций того модуля которому "принадлежит" эта переменная. Тогда и проблемы с переносом модуля в другие программы отпадут сами собой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Она может быть глобальная или нет.

Согласен с alekseykoj - если Вам нужно глобальную переменную, так делайте ее. Если возможность обойтись без глобальной переменной лучше без нее обойтись :)

В одном модуле .с- файла объявляете и инициализируте глобальную переменную а в .h файле этого же модуля объявляете ее как extern. И подключаете .h файл модуля к другим модулям где переменная используеться.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Единственное "противопоказание" следить за корректностью значения в переменной. (она же глобальная... Может быть изменена из нескольких модулей программы). Необходимо оформлять программу таким образом чтоб другие модули получали значение переменной или изменяли его с помощью функций того модуля которому "принадлежит" эта переменная. Тогда и проблемы с переносом модуля в другие программы отпадут сами собой.

 

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

 

Собственно с учетом всего этого и делаю. Уже давно, тема-то старенькая... Но вот чё-то заглянул.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Извиняюсь :blush: А так?

 

Извращение полное. Использовать динамическую память там где она апсалютно не нужна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...