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

 
 
> Язык С, ARM - простые вопросы
Slash
сообщение Jan 21 2009, 15:17
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 202
Регистрация: 10-04-05
Из: Санкт-Петербург
Пользователь №: 4 011



Здравствуйте!

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

А если программа строится в виде задач в бесконечном цикле:
Код
while (1)
{
    Task1();
    Task2();
    Task3();
}

Как обмениваться сообщениями между задачами? Мне понравилась система глобальных флагов - данные готовы к отправке, данные приняты, какое-то действие завершено и т.д.
Как без них?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
rezident
сообщение Jan 23 2009, 15:10
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Demeny @ Jan 23 2009, 12:34) *
Теперь мне нужно прикрутить в проект второй UART с той же функциональностью, третий, четвёртый ... И вообще - я, как менеджер проекта, не знаю, сколько у заказчика будет UART-ов. Как мне Ваш модуль с минимальными доработками несколько раз включить в проект ?
Что-то я не понял затруднений. Статические переменные объявленные внутри функции имеют область видимости в пределах этой функции. Статические переменные объявленные вне какой-либо функции имеют область видимости в пределах данного модуля. Разве не так?
Могу конечно ошибаться, но по-моему singlskv имел в виду как раз такой случай. Глобальная переменная (объявленная вне тела функции) типа static имеет область видимости в пределах данного модуля. Никто не мешает дублировать эти модули в требуемых количествах. Хотя конечно же, если модуль состоит из одной функции, то разумнее было бы объявить эти переменные как static, но внутри самой функции.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jan 23 2009, 15:57
Сообщение #3


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(rezident @ Jan 23 2009, 18:10) *
Могу конечно ошибаться, но по-моему singlskv имел в виду как раз такой случай. Глобальная переменная (объявленная вне тела функции) типа static имеет область видимости в пределах данного модуля. Никто не мешает дублировать эти модули в требуемых количествах. Хотя конечно же, если модуль состоит из одной функции, то разумнее было бы объявить эти переменные как static, но внутри самой функции.
примерно это я и имел в виду,
только одна функция это частный случай и тогда действительно переменные нужно определять как статические внутри функции,
а вот если несколько функций в модуле работают с одной статической переменной, то без глобальных определений никак не обойтись,
но ведь можно ограничить область видимости таких переменных...

Я вот совсем теперь не понимаю за что ратует Demeny,
совсем без глобальных переменных ну никак.., и сохранение состояния автомата это один из примеров,
возможно речь о том что не нужно к ним обращаться напрямую ? то есть нужно предоставить интерфейс через вызов функций ?
ну дык это и не очень большой вопрос, и в каждом проекте он решаеться в частном порядке...
Go to the top of the page
 
+Quote Post
Demeny
сообщение Jan 26 2009, 09:58
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(singlskv @ Jan 23 2009, 18:57) *
Я вот совсем теперь не понимаю за что ратует Demeny ...

Попробую ещё раз пояснить преимущества локальных переменных перед глобальными, пусть даже и статическими, т. е. видимыми в пределах одного программного модуля.
1) Если Ваш конечный автомат, или другой программный модуль (функция) хранит своё внутреннее состояние в статических или глобальных переменных, он тут же становится непригодным для многопоточного использования, проще говоря, становится "non-reenterable", во всяком случае, Вам придётся прибегнуть к специальным ухищрениям навроде синхронизации, чтобы использование Ваших функций в многопоточном приложении не вызвало крах всего приложения. Также она не может быть безопасно вызвана в качестве обработчика прерывания.
В случае локальных переменных всё безопасно - ведь у каждого потока свой стек, следовательно, каждый поток работает со своим уникальным набором переменных.
2) Ваш модуль в составе программы может вообще оказаться невостребованным (ну нет у клиента 8 UART-ов, заложенных по максимуму ...), однако память под буфера и прочие настройки Вы уже зарезервировали статически. Или же Ваш модуль нужен только на этапе инициализации - один раз при старте системы, а память занята уже "навсегда" ...
3) Доступ к локальным переменным осуществляется, как правило, быстрее, чем к глобальным (статическим), потому что любой оптимизирующий компилятор старается раскидать по возможности локальные переменные по регистрам процессора.
4) С точки зрения проектирования удобно представлять себе отдельную функцию, как законченный функциональный блок ("черный ящик") с входными и выходными параметрами. Это позволяет отлаживать функцию отдельно от остальных. Использование глобальных переменных размывает это понятие, поскольку, как ни крути, поведение функции зависит от поведения остальной части программы. Вот и будем ломать голову при отладке, какого же рожна глобальная переменная имеет "не то" значение, какое должно быть, и какая собака его испортила. Придётся бросить отладку текущей функции и заняться поиском "собаки". unsure.gif


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 26 2009, 10:32
Сообщение #5


Гуру
******

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



Цитата(Demeny @ Jan 26 2009, 12:58) *
1) Если Ваш конечный автомат, или другой программный модуль (функция) хранит своё внутреннее состояние в статических или глобальных переменных, он тут же становится непригодным....


Либо с точностью до наоборот - ПРИГОДНЫМ. Конечный автомат получает указатель на структуру с котрой работать в данный момент и работает. Кроме того, опять, если нужны сколь нибудь реально-сложные автоматы в многопоточном приложении, то по любому он нужен и эти проблемы придется решать и отнюдь "просто используем локальные переменные".

Цитата
Вы уже зарезервировали статически.


Статически-то зачем? Спросили сколько надо у менеджера памяти. А вот стек, который потребуется Вам для Вашего непрогнозируемого количества "UART-ов" Вы как раз скорее всего статически-то и выделите. 

Цитата
3) Доступ к локальным переменным осуществляется, как правило, быстрее, чем к глобальным (статическим)


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

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



Либо поведение этой функции ДОЛЖНО ЗАВИСЕТЬ от "остальной части" и тут Вас никакие ухищрения не заставят обойти эту зависимость. Либо НЕ зависят - в этом случае глубоко фиолетов глобальные или нет какие-то переменные, ибо в этом случае они по любому приватно находятся в пользовании одной функции.

 


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Jan 26 2009, 14:20
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(zltigo @ Jan 26 2009, 05:32) *
Статически-то зачем? Спросили сколько надо у менеджера памяти. А вот стек, который потребуется Вам для Вашего непрогнозируемого количества "UART-ов" Вы как раз скорее всего статически-то и выделите. 

 


Товарищи капиталисты, по-моему вы путаете теплое с мягким.

Глобальное - то, что видно отовсюду и всегда живет (возможно спорно),
Локальное - определено и живет в пределах обьекта к которому принадлежит.
Пример - переменные обьявленные внутри функции - локальные для етой функции (
совсем не обязательно они должны быть на стеке),
переменные обьявленные внутри класс/структуры - локальны для етих
классов/структур и глобально (без структуры/класса) - невидимы.
Могут размещатся в хипе, от етого глобальными не становятся.


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 26 2009, 14:49
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(A. Fig Lee @ Jan 26 2009, 18:20) *
Товарищи капиталисты, по-моему вы путаете теплое с мягким.
Глобальное - то, что видно отовсюду и всегда живет (возможно спорно),

Статическое - это то, что видно только там, где надо, и всегда живет. Не путайте мертвое  с пьяным smile.gif
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Jan 26 2009, 17:55
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(_Pasha @ Jan 26 2009, 09:49) *
Статическое - это то, что видно только там, где надо, и всегда живет. Не путайте мертвое  с пьяным smile.gif



смотря о каких языках говорил - C или C++?

2. живет не всегда. например, обьявленная внутри функции - с момента обращения к функции.


Цитата(zltigo @ Jan 26 2009, 10:22) *
Это у Вас каша sad.gif из глобальности и области видимости, на что я уже сразу указывал.


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


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jan 26 2009, 19:45
Сообщение #9


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(A. Fig Lee @ Jan 26 2009, 20:55) *
2. живет не всегда. например, обьявленная внутри функции - с момента обращения к функции.
Живет она как раз всегда, а вот увидеть ее мы можем другой функцией
только после обращения к фунцкии в которой она определена(а можем и не увидеть если не захотим...).

Вот с вашей точки зрения в таком коде:
Код
void someFunc()
{
  static unsigned char ch;
  ................
}

переменная ch глобальная или локальная ?


Разница между глобальными и локальными ИМХО, заключается в том что к глобальной(если захочу), могу обратиться
из любой другой функции, а вот к локальной только из функции в которой она создана.
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Jan 26 2009, 22:07
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(singlskv @ Jan 26 2009, 14:45) *
Вот с вашей точки зрения в таком коде:
Код
void someFunc()
{
  static unsigned char ch;
  ................
}

переменная ch глобальная или локальная ?


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


ok.

из Си стандарда. Немного неправильно обозвал глобальные, да.
Онако - время жизни статической переменной внутри функции
определено со времени входа в функцию

6.2.4 Storage durations of objects
1 An object has a storage duration that determines its lifetime. There are three storage
durations: static, automatic, and allocated. Allocated storage is described in 7.20.3.
2 The lifetime of an object is the portion of program execution during which storage is
guaranteed to be reserved for it.
An object exists, has a constant address,25) and retains
its last-stored value throughout its lifetime.26) If an object is referred to outside of its
lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime.
3 An object whose identifier is declared with external or internal linkage, or with the
storage-class specifier static has static storage duration. Its lifetime is the entire
execution of the program and its stored value is initialized only once, prior to program
startup.
4 An object whose identifier is declared with no linkage and without the storage-class
specifier static has automatic storage duration.
5 For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way.
(Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration is
reached in the execution of the block; otherwise, the value becomes indeterminate each
time the declaration is reached.
6 For such an object that does have a variable length array type, its lifetime extends from
the declaration of the object until execution of the program leaves the scope of the
declaration.27) If the scope is entered recursively, a new instance of the object is created
each time. The initial value of the object is indeterminate.


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jan 26 2009, 22:52
Сообщение #11


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(A. Fig Lee @ Jan 27 2009, 01:07) *
Немного неправильно обозвал глобальные, да.
ага, неправильно, и выделить нужно было другой текст:
3 An object whose identifier is declared with external or internal linkage, or with the
storage-class specifier static has static storage duration. Its lifetime is the entire
execution of the program and its stored value is initialized only once, prior to program
startup.

Обращу Ваше внимание что в этом пункте вобще ничего не сказанно про место где декларируется static identifier ...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Slash   Язык С, ARM - простые вопросы   Jan 21 2009, 15:17
- - aaarrr   Цитата(Slash @ Jan 21 2009, 18:17) Стоит ...   Jan 21 2009, 15:29
- - Demeny   Цитата(Slash @ Jan 21 2009, 18:17) Стоит ...   Jan 22 2009, 08:33
|- - aaarrr   Цитата(Demeny @ Jan 22 2009, 11:33) Прави...   Jan 22 2009, 09:09
|- - Demeny   Цитата(aaarrr @ Jan 22 2009, 12:09) Поясн...   Jan 22 2009, 10:20
- - aaarrr   Для отладки глобальные переменные наоборот удобнее...   Jan 22 2009, 11:29
|- - Demeny   Цитата(aaarrr @ Jan 22 2009, 14:29) Для о...   Jan 22 2009, 12:35
||- - aaarrr   Цитата(Demeny @ Jan 22 2009, 15:35) Всё э...   Jan 22 2009, 12:48
||- - singlskv   Цитата(Demeny @ Jan 22 2009, 15:35) Это с...   Jan 23 2009, 00:27
||- - Demeny   Цитата(singlskv @ Jan 23 2009, 03:27) В к...   Jan 23 2009, 07:34
||- - A. Fig Lee   Цитата(singlskv @ Jan 22 2009, 19:27) В к...   Jan 23 2009, 19:06
|- - VladimirYU   Цитата(aaarrr @ Jan 22 2009, 14:29) Для о...   Jan 22 2009, 12:52
|- - zltigo   Цитата(VladimirYU @ Jan 22 2009, 14:52) К...   Jan 22 2009, 13:05
|- - aaarrr   Цитата(VladimirYU @ Jan 22 2009, 15:52) Д...   Jan 22 2009, 13:05
- - sergeeff   Это скорее организационная проблема. Один человек ...   Jan 22 2009, 15:14
|- - zltigo   Цитата(sergeeff @ Jan 22 2009, 17:14) Это...   Jan 22 2009, 17:14
- - rezident   Я бы предложил спорщикам уточнить, для какой облас...   Jan 23 2009, 00:46
|||- - _Pasha   Цитата(A. Fig Lee @ Jan 26 2009, 21:55) 2...   Jan 26 2009, 18:33
||||- - sonycman   Цитата(_Pasha @ Jan 26 2009, 22:33) стати...   Jan 26 2009, 20:17
||||- - singlskv   Цитата(sonycman @ Jan 26 2009, 23:17) А е...   Jan 26 2009, 20:27
||||- - rezident   Цитата(singlskv @ Jan 27 2009, 01:27) Бол...   Jan 26 2009, 20:40
|||||- - singlskv   Цитата(rezident @ Jan 26 2009, 23:40) Раб...   Jan 26 2009, 21:29
|||||- - sonycman   Цитата(singlskv @ Jan 27 2009, 01:29) Вас...   Jan 26 2009, 21:51
|||||- - Dima_G   Цитата(singlskv @ Jan 27 2009, 01:29) Я э...   Jan 28 2009, 10:21
|||||- - A. Fig Lee   Цитата(Dima_G @ Jan 28 2009, 05:21) Локал...   Jan 28 2009, 14:45
||||- - sonycman   Цитата(singlskv @ Jan 27 2009, 00:27) Пер...   Jan 26 2009, 21:07
|||- - zltigo   Цитата(A. Fig Lee @ Jan 27 2009, 01:07) О...   Jan 26 2009, 22:52
|||- - A. Fig Lee   Цитата(singlskv @ Jan 26 2009, 17:52) ага...   Jan 26 2009, 23:46
||- - zltigo   Цитата(A. Fig Lee @ Jan 26 2009, 17:20) Т...   Jan 26 2009, 15:22
|- - Dog Pawlowa   Цитата(Demeny @ Jan 26 2009, 12:58) Попро...   Jan 26 2009, 10:45
|- - _Pasha   Цитата(Dog Pawlowa @ Jan 26 2009, 13:45) ...   Jan 26 2009, 11:13
|- - Dog Pawlowa   Цитата(_Pasha @ Jan 26 2009, 14:13) Есть ...   Jan 26 2009, 15:10
|- - _Pasha   Цитата(Dog Pawlowa @ Jan 26 2009, 18:10) ...   Jan 26 2009, 15:23
|- - zltigo   Цитата(_Pasha @ Jan 26 2009, 18:23) Один ...   Jan 26 2009, 15:25
- - Goodefine   Я, вот, по простому спрошу... Допустим, имеем обра...   Jan 23 2009, 19:09
|- - A. Fig Lee   Цитата(Goodefine @ Jan 23 2009, 14:09) Я,...   Jan 24 2009, 03:01
|- - VladimirYU   Цитата(A. Fig Lee @ Jan 24 2009, 06:01) п...   Jan 24 2009, 08:23
|- - zltigo   Цитата(A. Fig Lee @ Jan 24 2009, 05:01) п...   Jan 24 2009, 08:47
|- - _Pasha   Цитата(zltigo @ Jan 24 2009, 11:47) Их до...   Jan 24 2009, 14:43
|- - A. Fig Lee   Цитата(zltigo @ Jan 24 2009, 03:47) Опять...   Jan 24 2009, 17:14
|- - zltigo   Цитата(A. Fig Lee @ Jan 24 2009, 20:14) н...   Jan 24 2009, 17:50
|- - A. Fig Lee   Цитата(zltigo @ Jan 24 2009, 12:50) Ага, ...   Jan 25 2009, 13:43
- - Serj78   Можно, я свои 5 копеек вставлю? Иногда , на мало...   Jan 24 2009, 08:14
- - A. Fig Lee   вот правильный стандард - C++: The zeroinitializa...   Jan 27 2009, 14:42
|- - zltigo   Цитата(A. Fig Lee @ Jan 27 2009, 17:42) в...   Jan 27 2009, 16:10
||- - A. Fig Lee   Цитата(zltigo @ Jan 27 2009, 11:10) Вы, к...   Jan 27 2009, 16:23
|- - singlskv   Цитатакстати, я все никак не добьюсь - речь о C ил...   Jan 27 2009, 22:27
|- - A. Fig Lee   Цитата(singlskv @ Jan 27 2009, 17:27) Ну ...   Jan 27 2009, 23:44
- - rezident   Модератор. Тема закрыта по просьбе топикстартера.   Feb 2 2009, 21:01


Closed TopicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 01:55
Рейтинг@Mail.ru


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