Как избежать глобалов в C? - PullRequest
3 голосов
/ 02 августа 2010

как начинающий, я читаю везде, чтобы избежать чрезмерного использования глобальных переменных. Ну как это сделать? Мой низкий навык терпит неудачу. Я заканчиваю тем, что пропускаю тонны структур, и это труднее читать, чем использование глобалов. Ага, мой код беспорядок, какая-либо хорошая книга / рекомендация статьи, которая ведет через эту проблему / дизайн структуры приложения?

Ответы [ 5 ]

8 голосов
/ 02 августа 2010

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

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

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

У меня МНОГО любимых книг по стилю программирования, но я думаю, что лучшее, что я знаю для решения этой ситуации, это Элементы стиля программирования , написанные Керниганом и Плаугером. Он довольно старый, и его трудно найти, но короткий, сладкий, и его стоит найти где-нибудь используемым.

Это не так коротко, не так приятно, но все же стоит найти Code Complete, 2nd edition . Это намного более подробно, предоставляет гораздо больше кода и предоставляет гораздо больше разнообразия, участвующих в разработке программного обеспечения. Это отлично, но может быть более пугающим.

Нет ничего лучше, чем учить магистров: код в Расширенное программирование в среде Unix, 2-е издание феноменален и стоит каждого часа обучения.

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

1 голос
/ 02 августа 2010

Я бы предложил Структурированный дизайн от Yourdon и Constantine.Старая книга по компьютерным стандартам (в ней есть примеры с кассетами!), Но она очень хорошо подходит для ваших проблем.

0 голосов
/ 02 августа 2010

@ PeterK Проблема в том, что сама структура всегда представлена ​​в книгах на Си как контейнер, который можно многократно объявлять / передавать различным функциям, и это может сбить меня с толку, и я никогда не думал использовать ее как один экземпляр глобального контейнера (и это может сделать мой код более читабельным).

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

  1. Упаковать некоторую глобальную информацию в структуру в соответствии с функцией ex. (sInverterState, sButtonsState, sInverterParameters и т. д.)
  2. Если я пишу пользовательский интерфейс меню, я могу использовать статические переменные в C-файле и не заботиться о прохождении структур, когда у меня только 1 ЖК-дисплей. Я не хочу, чтобы это выглядело как GTK ++.
  3. Написание кода для реетранта еще не для меня, и это перебор для этой цели.
  4. Получите надлежащее образование в области информационных технологий.

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

0 голосов
/ 02 августа 2010

Если ваша программа - это своего рода «маленький» проект, где глобальные переменные не так уж плохи, но вы думаете, что в будущем вам может понадобиться интегрировать их в более крупный проект, очень простое решение - добавить одинуказатель контекста для каждой функции и хранение всех ваших «глобальных» переменных там.Если вы всегда называете это одно и то же, вы можете даже делать такие вещи, как:

#define current_filename   context->current_filename
#define option_flags       context->option_flags

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

0 голосов
/ 02 августа 2010

Вот два варианта, которые вы можете использовать для улучшения ситуации:

  1. Для структур, доступных только для чтения, есть функции, которые могут управлять доступом к данным с помощью константного указателя:

    struct my_struct;

    const my_struct * GetMyStruct (void) const;

  2. Ограничьте экспозицию глобальной структуры, объявив ее статической.Таким образом, он будет иметь только область действия файла:

    статический mystruct myStructInstance;

...