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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Немного стандарта написания программ на С, применительно к контроллерам
ar__systems
сообщение Dec 4 2009, 02:35
Сообщение #16


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Цитата(Dima_G @ Oct 26 2009, 05:22) *
1. именно этим и плохо. Разово нужная переменная постоянно занимает память.
2. программы с глобальными переменными очень плохо читаются (ну это мое субъективное мнение)
3. глобальная - доступна всем желающим (во всей программе, либо в единице трансляции, если это - статик). Можно посадить трудноуловимые баги smile.gif.
4, Трудность переноса кода - если функция использует только локальные переменные, ее в общем случае можно просто "взять и выдернуть". Использующая глобальные переменные функция, потянет за собой хвост этих переменных...

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

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

Сообщение отредактировал ar__systems - Dec 4 2009, 02:35
Go to the top of the page
 
+Quote Post
alekseykoj
сообщение Dec 14 2009, 06:35
Сообщение #17


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 8-11-05
Пользователь №: 10 602



Можно пользоваться указателями
например вот так:
Код
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();
}

Но в этом случае надо следить за указателем. Чтоб к нему не было обращений, когда он еще не инициализирован или динамическая структура уже освобождена
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 14 2009, 07:40
Сообщение #18


Гуру
******

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



Цитата(alekseykoj @ Dec 14 2009, 08:35) *
Можно пользоваться указателями
Можно, но какой смысл? Заводим локальную переменную в main() и через указатель делаем ее как-бы глобальной. Какие преимущества это дает по сравнению с обычной глобальной переменной? Т.е. ради чего занимается лишняя память под указатель и ради чего мы вынуждаем процессор постоянно обращаться к структуре косвенно?
Цитата(alekseykoj @ Dec 14 2009, 08:35) *
например вот так:
Вот так делать не нужно ни в коем случае. Вместо того, чтобы завести указатель на нужный тип и позволить компилятору контролировать ваши описки, вы заводите указатель на void * и вынуждены при каждом обращении вручную, принудительно приводить его к нужному типу. Компилятор не имеет возможности проверить, совместим ли объект, на который указывает указатель и тот тип, к которому вы его приводите методом грубой силы.
Цитата(alekseykoj @ Dec 14 2009, 08:35) *
Код
void Proc1(void)
{
  h_VarA->alpha = 123;  
}
Не скомпилится. h_VarA - указатель на void
Цитата(alekseykoj @ Dec 14 2009, 08:35) *
Код
  h_VarA = (void*)&keyboard;
Явное приведение лишнее. Любой не-cv (const и/или volatile) указатель приводится к void * неявно.

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


--------------------
На любой вопрос даю любой ответ
"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
alekseykoj
сообщение Dec 14 2009, 09:56
Сообщение #19


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 8-11-05
Пользователь №: 10 602



Цитата
Можно, но какой смысл? Заводим локальную переменную в 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;

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

}


Преимущества перед глобальной созданной статически в том, что я сам контролирую выделенные ресурсы и в любой момент могу освободить память для размещения другой структуры.
Go to the top of the page
 
+Quote Post
OLEG_BOS
сообщение Dec 14 2009, 10:44
Сообщение #20


Местный
***

Группа: Свой
Сообщений: 386
Регистрация: 1-12-05
Пользователь №: 11 639



Цитата(alekseykoj @ Dec 14 2009, 11:56) *
Вообще, для этих целей есть операторы new и delete. Которые позволяют контролировать выделяемые ресурсы в момент работы программы.

Если мне не изменяет склероз, то операторы динамического распределения памяти new и delete отсутствуют в С и есть только в С++ , а топик вроде был как о С smile.gif
alekseykoj, а для каких Вы PIC-контроллеров пишете на С++? smile.gif
Go to the top of the page
 
+Quote Post
alekseykoj
сообщение Dec 14 2009, 11:58
Сообщение #21


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 8-11-05
Пользователь №: 10 602



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

Код
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);

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

}
Go to the top of the page
 
+Quote Post
torik
сообщение Dec 14 2009, 13:49
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 113
Регистрация: 1-11-05
Пользователь №: 10 359



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


--------------------
Быть. torizin-liteha@yandex.ru
Go to the top of the page
 
+Quote Post
alekseykoj
сообщение Dec 14 2009, 14:08
Сообщение #23


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 8-11-05
Пользователь №: 10 602



Ну и делай ее глобальной. Ни каких "противопоказаний" нет. Единственное "противопоказание" следить за корректностью значения в переменной. (она же глобальная... Может быть изменена из нескольких модулей программы). Необходимо оформлять программу таким образом чтоб другие модули получали значение переменной или изменяли его с помощью функций того модуля которому "принадлежит" эта переменная. Тогда и проблемы с переносом модуля в другие программы отпадут сами собой.
Go to the top of the page
 
+Quote Post
OLEG_BOS
сообщение Dec 14 2009, 14:24
Сообщение #24


Местный
***

Группа: Свой
Сообщений: 386
Регистрация: 1-12-05
Пользователь №: 11 639



Цитата(torik @ Dec 14 2009, 15:49) *
Она может быть глобальная или нет.

Согласен с alekseykoj - если Вам нужно глобальную переменную, так делайте ее. Если возможность обойтись без глобальной переменной лучше без нее обойтись smile.gif
В одном модуле .с- файла объявляете и инициализируте глобальную переменную а в .h файле этого же модуля объявляете ее как extern. И подключаете .h файл модуля к другим модулям где переменная используеться.
Единственным "противопоказанием" может быть использование этой переменной в функции обработчике прерывания, в таком случае глобальной переменной нужно еще и volatile добавить при ее обявлении в с. файле модуля
Go to the top of the page
 
+Quote Post
torik
сообщение Dec 14 2009, 14:37
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 2 113
Регистрация: 1-11-05
Пользователь №: 10 359



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


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


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


--------------------
Быть. torizin-liteha@yandex.ru
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Dec 15 2009, 14:49
Сообщение #26


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Цитата(alekseykoj @ Dec 14 2009, 06:58) *
Извиняюсь blush.gif А так?


Извращение полное. Использовать динамическую память там где она апсалютно не нужна.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 7th July 2025 - 10:03
Рейтинг@Mail.ru


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