Шрифт:
Шаг 4 называется более формально целочисленным расширением. Преобразование операндов нормально проходит в большинстве ситуаций, хотя следует отметить следующие особенности.
Преобразование char в int может вызвать на некоторых машинах расширение на знаковый бит, если char не объявлен как unsigned.
Преобразование целого типа с атрибутом signed в целый тип большего раз-мера вызывает расширение влево за счет знакового бита; преобразование целого типа с атрибутом unsigned в целый тип большего размера вызывает заполнение левою бита нулем.
Преобразование любого значения в _Воо1 дает значение 0, если значение равно нулю, и 1 в противном случае.
Преобразование более длинного целого типа в более короткий вызывает усечение целого значения слева.
Преобразование типа с плавающей точкой в целый тип вызывает усечение дробной части значения. Если целый тип является недостаточным, чтобы вместить преобразованное значение с плавающей точкой, то результат яв-ляется неопределенным (как и в случае преобразования отрицательного значения с плавающей точкой в целое с атрибутом unsigned).
Преобразование более длинного значения с плавающей точкой в более ко-роткий тип может вызывать или не вызывать округление, прежде произой-дет усечение. Классы памяти и область действия
Термин класс памяти (storage class) относится к способу выделения памяти ком-пилятором и к области действия определения конкретной функции или метода. Классы памяти — это auto, static, extern и register. Класс памяти можно не указывать в объявлении, и он будет назначен по умолчанию, как это описывается ниже.
Термин область действия (scope) относится к границам действия определенного идентификатора внутри программы. Идентификатор, определенный вне любой функции, метода или блока операторов (мы будем называть здесь это БЛОКОМ), доступен для ссылки в любой последующей точке файла. Идентификаторы, определенные внутри БЛОКА, являются локальными относительно этого БЛОКА и могут локально переопределять идентификатор, определенный вне этого БЛОКА. Имена меток, а также имена формальных параметров известны во всем БЛОКЕ. Метки, переменные экземпляра, имена структур и компонентов структур, имена объединений и компонентов объединений, а также имена перечислимых типов данных не обязательно должны отличаться друг от друга или от имен переменных, функций или методов. Однако идентификаторы перечисления все же должны отличаться от имен переменных и от других идентификаторов перечисления, определенных в пределах одной области действия. Имена классов имеют глобальную область действия и должны отличаться от имен других переменных и типов в пределах одной области действия. Функции
Если при определении функции определяется класс памяти, он должен быть указан как static или extern. К функции, которая объявляется как static, можно обращаться только в пределах файла, который содержит эту функцию. Функ-ции, объявленные как extern (или функции, для которых не указан никакой класс), могут вызываться функциями или методами из других файлов. Переменные
В таблице В.5 приводится сводка различных классов памяти, которые могут использоваться в объявлении переменных, а также их области действия и спо-собы их инициализации.
Табл. В.5. Переменные: сводка классов памяти, областей действия и способов инициализации Класс памяти Место объявления переменной На нее можно ссылаться И инициализировать с помощью Комментарии static Вне любого БЛОКА Внутри данного файла Только константного выражения Переменные инициализируются только один раз при запуске программы; значения сохраняются в пределах БЛОКОВ; значение по умолчанию 0 Внутри какого-либо БЛОКА Внутри этого блока extern Вне любого блока Внутри данного файла Только константных выражения Переменная должна быть определена хотя бы в одном месте без ключевого слова extern или в одном месте с использованием ключевого слова extern с присваиванием начального значения. Внутри какого-либо БЛОКА Внутри этого блока auto Внутри какого-либо БЛОКА Внутри этого блока Любого допустимого выражения Переменная инициализируется каждый раз при входе в БЛОК; нет никакого значения по умолчанию. register Внутри какого-либо БЛОКА Внутри этого блока Любого допустимого выражения Присваивание регистра (register) не гарантируется; разнообразные ограничения на типы переменных, которые могут быть объявлены; нельзя брать адрес переменной с register; инициализируется каждый раз при входе в этот БЛОК; нет никакого значения по умолчанию. Не указан Вне любого блока Внутри данного файла или из других файлов, которые содержат соответствующие объявления Только константного выражения Это объявление может появляться только в одном месте; переменная инициализируется при запуске программы; значение по умолчанию 0; по умолчанию используется класс памяти auto. Внутри какого-либо БЛОКА (См. auto) (См. auto) Переменные экземпляра
К переменным экземпляра можно получать доступ с помощью любого метода экземпляра, определенного для данного класса в секции interface, где явно объявляется эта переменная, или в категориях, созданных для данного класса. К наследуемым переменным экземпляра тоже можно осуществлять непосред-ственный доступ без каких-либо специальных объявлений. Методы класса не имеют доступа к переменным экземпляра.
Для управления областью действия переменной экземпляра можно исполь-зовать специальные директивы @private, @protected и @риЫк. После появления этих директив они действуют, пока не встретится закрывающая фигурная скобка, заканчивающая объявление соответствующих переменных экземпляра, или пока не будет использована другая из этих трех директив. Например, следующие строки являются началом объявления секции interface для класса с именем Point, содержащего четыре переменные экземпляра. @interface Point: NSObject { @private int internail D; @protected float x; float y; @public BOOL valid; }
Переменная internallD объявлена как private, переменные x и у — как protected (директива по умолчанию), переменная valid — как public.
Эти директивы описываются в таблице В.6.
Табл. В.6. Область действия переменных экземпляра Директива На переменную можно ссылаться Комментарии @protected С помощью методов экземпляра в данном классе, методов экземпляра в подклассах, и методов экземпляра в расширениях категорий на данный класс. Эта директива по умолчанию. @private С помощью методов экземпляра в данном классе, методов экземпляра в расширениях категорий на данный класс, но не из каких-либо подклассов. Эта директива ограничивает доступ самим классом. @public С помощью методов экземпляра в данном классе, методов экземпляра в подклассах и методов экземпляра в расширениях категорий на данный класс; доступ к такой переменной можно также выполнять из других функций или методов, применяя к экземпляру класса оператор косвенного указателя структуры (->), после которого следует имя переменной экземпляра (например, myfract->numerator). Эту директиву следует использовать только при необходимости; она нарушает понятие инкапсуляции данных. Функции