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

Язык С, ARM - простые вопросы

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

 

Стоит ли пользоваться глобальными переменными и можно ли без них обойтись?

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

 

А если программа строится в виде задач в бесконечном цикле:

while (1)
{
    Task1();
    Task2();
    Task3();
}

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

Как без них?

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


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

Стоит ли пользоваться глобальными переменными и можно ли без них обойтись?

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

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

 

Мне понравилась система глобальных флагов - данные готовы к отправке, данные приняты, какое-то действие завершено и т.д.

Как без них?

Нормальная система.

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


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

Стоит ли пользоваться глобальными переменными и можно ли без них обойтись?

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

Правильно пишут. Пока проект небольшой (до 10 файлов на С) - это несущественно, а в больших проектах (особенно многопоточных) обилия глобальных переменных лучше избегать - замучаетесь с отладкой.

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

А если программа строится в виде задач в бесконечном цикле:

while (1)
{
    Task1();
    Task2();
    Task3();
}

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

Как без них?

Например, так.

while (1)
{ 
    int Msg1, Msg2, Msg3;
            
    Task1(&Msg1, &Msg2);
    Task2(&Msg3, &Msg2);
    Task3(&Msg1);
}

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


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

Правильно пишут. Пока проект небольшой (до 10 файлов на С) - это несущественно, а в больших проектах (особенно многопоточных) обилия глобальных переменных лучше избегать - замучаетесь с отладкой.

Поясните, пожалуйста, каким это образом глобальные переменные мешают отладке?

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


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

Поясните, пожалуйста, каким это образом глобальные переменные мешают отладке?

При их обилии, они запутывают логику выполнения программы (и без того запутанную :smile3046: ). Поскольку инициализируется переменная в одном месте, модифицируется в другом, а используется ещё в десятке разных мест (на то она и глобальная переменная).

Также им нужно придумывать уникальные имена, а при сходной функциональности эти имена будут примерно такие - Counter27, Sigma7, Delta18, Sum88, что тоже не добавляет читабельности коду.

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


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

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

 

Уникальные и осмысленные имена нужно просто научиться придумывать, имена типа Counter27, Sigma7 возникают как раз из-за недостатка этого умения.

 

Без глобальных переменных обойтись нельзя. Попытка использовать локальную переменную там, где нужна глобальная, запутает программу гораздо сильнее. Поэтому книжные утверждения, что де "плохой тон" следует отметать как бредовые. Нужно просто разумно использовать и те, и другие.

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


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

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

Это справедливо, если проект маленький.

В большом проекте отладку каждого модуля (функции) удобно производить отдельно, особенно если они написаны разными людьми. Для этого нужно уметь быстро собрать модуль и проверить (отладить) его функционирование. А если он усеян декларациями "extern ...", то мало того, что для его запуска потребуется определять все эти переменные локально, так ещё и сделает этот модуль нелинкуемым в составе проекта, если ту или иную глобальную переменную удалят другие разработчики. Всё это влечёт за собой геморрой необходимость ведения Конвенции по глобальным переменным в рамках проекта, и т. п.

И ещё важный момент. Если Вы в своём модуле "нечаянно" измените логику работы с глобальным объектом, остальные разработчики об этом так и не узнают, только программа из-за возможной Вашей ошибки в целом может оказаться в один момент неработоспособной, и простыми средствами "поймать за руку" поломавшийся модуль не представляется возможным, повторюсь, особенно в многопоточном приложении. Зато если Вы поменяете перечень вызываемых параметров, их тип или количество ( "ну, не использую я более переменную Sum --> удаляю её из перечня параметров моей функции!" ) - это тут же выяснится ещё на этапе компиляции-линковки, и остальные разработчики смогут внести изменения в свои тексты.

 

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

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

--------------------------

Такая же история с оператором "goto". В принципе, в С можно без него обойтись. Но есть случаи, где его применение улучшает читабельность и логическую структуру кода, проще говоря, удобно. Однако заменять все циклы оператором "goto" - это "дурной тон".

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


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

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

А как без нее вообще можно обойтись? Если глобальные объекты используются в качестве интерфейсов между различными частями проекта, то они в любом случае должны быть согласованы. Но это далеко не единственный вариант, глобальные переменные могут использоваться и только в пределах модуля, а здесь никаких ограничений нет.

 

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

Разумеется, но обратная ситуация - не менее, если не более дурной.

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


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

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

 

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

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


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

Как правило, даже в сложном, но грамотно спроектированном проекте, глобальных переменных единицы.

Глупости то какие :( у меня вот прямо сечас добрых 64K глобальных динамичеки создаваемых структур (не считая прочих глобальных )по которым бегают десятки подпрограмм.

 

Смею утверждать, что проект cпроектирован грамотно :).

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


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

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

И что же с этой переменной делать? Промежуточный результат - это не обязательно одинокий int.

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


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

Это скорее организационная проблема. Один человек ведет весь проект или коллектив. При коллективной работе глобальные переменные раскиданные по разным модулям и библиотекам - абсолютный кошмар для программистов.

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


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

Это скорее организационная проблема.

 

 

Это ВООБЩЕ НЕ ПРОБЛЕМА и уж тем более не организационая. Либо глобальные данные принципиально нужны, либо нет.

При коллективной работе глобальные переменные раскиданные по ...

Хоть при коллективной, хоть любой другой РАБОТЕ а бездумном бумагомарательстве, глобальные данные, структуры, поля, биты описываются ЕДИНОЖДЫ в хидерах. Дополнительно для доступа к данным c целью сокрытия ненужных подробностей можно иметь макросы/функции. И никакого кошмара.

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


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

Это справедливо, если проект маленький.
ИМХО, это совсем не так, ну посмотрите на Linux например...

В большом проекте отладку каждого модуля (функции) удобно производить отдельно, особенно если они написаны разными людьми. Для этого нужно уметь быстро собрать модуль и проверить (отладить) его функционирование. А если он усеян декларациями "extern ...", то мало того, что для его запуска потребуется определять все эти переменные локально, так ещё и сделает этот модуль нелинкуемым в составе проекта, если ту или иную глобальную переменную удалят другие разработчики. Всё это влечёт за собой геморрой необходимость ведения Конвенции по глобальным переменным в рамках проекта, и т. п.
По моему Вы смешиваете в одном понятии совсем разные вещи,

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

Вы можете сделать их доступными для других модулей(например через extern), а можете и не делать,

более того Вы можете сделать их доступными для одной части других модулей и недоступными для другой(например через препроцессор, ну или еще много как).

 

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

 

В качестве примера, пусть есть некий программный автомат который чего-нить там куда-нить отсылает/пишет/итд

Так вот у него есть функции или глобальные переменные видимые из вне которые запускают действие, и есть

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

куча ГЛОБАЛЬНЫХ но невидимых из вне переменных которые содержат в себе все внутреннее состояние автомата.

Такой модуль вполне независим и множество таких модулей может работать в одной проге не мешая друг другу,

нужно только описать "Конвенцию..." по входным и выходным параметрам.

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


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

Я бы предложил спорщикам уточнить, для какой области приложений они обсуждают полезность/вредность глобальных переменных? Одно дело писать под Windows, где размеры стека и кучи особо не волнуют программиста. И совсем другое дело писать для МК с очень ограниченными ресурсами ОЗУ, где "наползание" стека на область статических данных нередкая и весьма трудновылавливаемая ошибка. Вот где нужно искать компромисс между глобальными/статическими и локальными (стековыми) переменными!

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


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

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...