Лучшая практика использования статических переменных в C

Глобальные переменные обычно считаются плохой практикой программирования

В C, являются статическими переменными (то есть с областью модуля (файла)), которые считаются ОК?

Моя мысль заключалась в том, что переменные-члены в объектно-ориентированном языке не могут быть намного менее опасными, чем статические переменные в C, а переменные-члены, по-видимому, считаются хорошими.

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

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

Ответ 1

Переменные Static (file-scope) в C аналогичны статическим переменным-членам в С++.

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

Лучшим аналогом для нестатических переменных-членов является член структуры. Просто соберите свои "переменные-члены" в структуре и передайте эту структуру как параметр "this".

Ответ 2

Большая разница: с переменными-членами вы можете иметь несколько объектов, каждая из которых имеет свою собственную переменную-член. С помощью статических переменных области модуля у вас есть только один экземпляр переменной.

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

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

И вы можете предпочесть группировать свои статические или глобальные данные в больших struct -s.

Ответ 6

В контексте, который вы пытаетесь использовать, переменные модуля, вероятно, являются плохими идеями. Приятная вещь о передаче всего по параметрам заключается в том, что вам сложно выйти из синхронизации с вашими вызовами метода. Каждый метод делает что-то и передает некоторый компонент этого значения другому методу, поэтому его легко отслеживать - переменные живут только во время вызова метода. Сложнее отлаживать, если переменные существуют где-то в другом месте - такие вещи, как использование устаревшей переменной, от невозможного до вероятного.

Статические переменные обычно используются в качестве флагов - общий - логический, который вы задаете, чтобы изменить режим всего модуля тонким способом (квазистроенный - DEBUG).