Ключевые понятия
Язык С предлагает несколько моделей управления памятью. Вы должны ознакомиться со всеми различными вариантами. Вы также должны выработать критерии, когда выбирать тот или иной тип. Большую часть времени наилучщим выбором будет автоматическая переменная. Если вы решите применять другой тип, то для этого должны иметь вескую причину. При взаимодействии между функциями обычно лучше всего использовать автоматические переменные, параметры функций и возвращаемые значения, а не глобальные переменные. С другой стороны, глобальные переменные особенно удобны для представления константных данных.
Вы должны понимать свойства статической памяти, автоматической памяти и выделенной памяти. В частности, имейте в виду, что объем применяемой статической памяти определяется на этапе компиляции, а статические данные загружаются в память при загрузке программы. Память под автоматические переменные выделяется и освобождается во время выполнения, поэтому объем памяти, занимаемой автоматическими переменными, на протяжении выполнения программы меняется. Автоматическую память можно представлять как перезаписываемое рабочее пространство. Выделенная память увеличивается и уменьшается в объеме, но в этом случае процесс управляется вызовами функций, а не происходит автоматически.
Резюме
Память, задействованная под хранение данных в программе, может быть охарактеризована продолжительностью хранения, областью видимости и связыванием. Продолжительность хранения бывает статической, автоматической или выделенной. При статической продолжительности хранения память выделяется в начале выполнения программы и остается занятой на протяжении всего периода выполнения. Если продолжительность хранения является автоматической, то память под переменную выделяется, когда поток управления программы входит в блок, в котором переменная определена, и освобождается, когда управление покидает этот блок. В случае выделенной продолжительности хранения память выделяется вызовом malloc() (или родственной функции) и освобождается вызовом free().
Область видимости определяет, какие части программы могут иметь доступ к данным. Переменная, определенная вне любых функций, имеет область видимости в пределах файла и видна любой функции, определенной после объявления этой переменной. Переменная, определенная внутри блока или в качестве параметра функции, имеет область видимости в пределах блока и видна только этому блоку и всем вложенным в него блокам.
Связывание описывает диапазон, в пределах которого переменная, определенная в одной единице программы, может быть привязана к какой-то другой ее единице. Переменные с областью видимости в пределах блока, будучи локальными, не имеют связывания. Переменные с областью видимости в пределах файла, имеют внутреннее или внешнее связывание. Внутреннее связывание означает, что переменная может использоваться только в файле, содержащем ее определение. Внешнее связывание означает, что переменная может применяться также и в других файлах.
524 Глава 12
Ниже описаны классы хранения в С (кроме концепций, относящихся к потокам).
• Автоматический. Переменная, объявленная в блоке (или в качестве параметра в заголовке функции) без модификатора класса хранения или с модификатором класса хранения auto, принадлежит к автоматическому классу хранения. Она характеризуется автоматической продолжительностью хранения, областью видимости в пределах блока и отсутствием связывания. Если она не инициализирована, то ее значение не определено.
• Регистровый. Переменная, объявленная в блоке (или в виде параметра в заголовке функции) с модификатором класса хранения register, принадлежит к регистровому классу хранения. Она характеризуется автоматической продолжительностью хранения, областью видимости в пределах блока и отсутствием связывания. Адрес такой переменной получать нельзя. Объявление переменной как регистровой — это подсказка компилятору о необходимости обеспечить насколько возможно быстрый доступ. Если она не инициализирована, то ее значение не определено.
• Статический, без связывания. Переменная, объявленная в блоке с модификатором класса хранения static, принадлежит к классу хранения “статический, без связывания”. Она характеризуется статической продолжительностью хранения, областью видимости в пределах блока и отсутствием связывания. Такая переменная инициализируется только один раз на этапе компиляции. Если она не инициализирована явно, ее биты устанавливаются в 0.
Читать дальше