Причины использования статических функций и переменных в C

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

стандартный способ построить программу на C, как я вижу, это:

  • есть куча файлов c, определяющих функции и переменные, возможно, область ограничена static.
  • есть куча H файлов, объявляющих функции и, возможно, переменные соответствующего файла c, для других файлов c для использования. Закрытые функции и переменные не опубликовано в H-файле.
  • каждый файл c компилируется отдельно в файл o.
  • все o файлы связаны вместе с файлом приложения.

Я вижу две причины для объявления гобала static, Если переменная все равно не опубликована в файле h:

  • для удобочитаемости. Сообщите будущим читателям, включая меня, что переменная не доступна ни в одном другом файле.
  • во-вторых, чтобы предотвратить другой c файл с повторное объявление переменной как extern. Я полагаю, что компоновщику не понравится переменная, являющаяся обоими extern и static. (Мне не нравится идея файла, объявляющего переменную, принадлежащую кому-то другому, как extern, это нормально практикой?)

любая другая причина?

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

6 ответов


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

переопределение a static переменная as extern невозможно, но компилятор (как обычно) даст вам достаточно веревки, чтобы повеситься.

если я пишу static int foo; и int foo; в другой они считаются различными переменными, несмотря на то, что имя и тип - компилятор не будет жаловаться, но вы, вероятно, очень запутаетесь позже, пытаясь прочитать и / или отладить код. (Если я напишу extern int foo; во втором случае это не сможет связать, если я не объявлю нестатический int foo; где-то еще.)

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


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


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


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


Если вы объявите переменную foo в файле a.c, не делая его статическим, и переменная foo в файле b.c не делая его статическим, оба автоматически extern, что означает, что компоновщик может пожаловаться, если вы инициализируете оба, и назначить то же место памяти, если он не жалуется. Ожидайте удовольствия от отладки кода.

Если вы пишете функцию foo () в файле a.c, не делая его статическим, и функция foo () в файле b.c не делая его статическим, компоновщик может жаловаться, но если он нет, все вызовы foo () будут вызывать одну и ту же функцию. Ожидайте удовольствия от отладки кода.


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

Я люблю держать папку для вспомогательных классов для большинства моих проектов, которые в основном состоят из статических методы, чтобы делать вещи быстро и эффективно на лету, никаких объектов не нужно!