Спецификаторы класса памяти

ниже перечисляются спецификаторы класса памяти: спецификатор _ класса _ памяти: auto static extern register typedef Спецификатор typedef не резервирует память и называется"спецификатором класса памяти" только по синтаксическимсоображениям; это обсуждается ниже. Смысл различных классовпамяти был обсужден ранее (см. "Объекты языка Си"). Описания auto, static и register служат также вкачестве определений в том смысле, что они вызывают резерви-рование нужного количества памяти. В случае extern должноприсутствовать внешнее определение указываемых идентификато-ров где то вне функции, в которой они описаны. Описание register лучше всего представлять себе какописание auto вместе с намеком компилятору, что описанныетаким образом переменные будут часто использоваться. Эффек-тивны только несколько первых таких описаний. Кроме того, в -22- регистрах могут храниться только переменные определенныхтипов; на CM-ЭВМ это int, char или указатель. Существует идругое ограничение на использование регистровых переменных:к ним нельзя применять операцию взятия адреса &. При разум-ном использовании регистровых описаний можно ожидать получе-ния меньших по размеру и более быстрых программ, но в буду-щем улучшение генерирования кодов может сделать их ненуж-ными. В компиляторе для СМ ЭВМ воспринимаются первые 3 описа-ния register в каждой функции. Описание может содержать не более одного спецификаторакласса памяти. Если описание не содержит спецификаторакласса памяти, то считается, что он имеет значение auto,если описание находится внутри некоторой функции, и extern впротивном случае. Исключение: функции никогда не бываютавтоматическими.

Спецификаторы типа

Ниже перечисляются спецификаторы типа. спецификатор _ типа: char short int long unsigned float double спецификатор _ структуры _ или _ объединения спецификатор _ перечисления определяющее _ тип _ имя Слова long, short и unsigned можно рассматривать как прила-гательные; допустимы следующие комбинации: short int long int unsigned int long float Последняя комбинация означает то же, что и double. В осталь-ном описание может содержать не более одного спецификаторатипа. Если описание не содержит спецификатора типа, то счи-тается, что он имеет значение int. Спецификаторы структур и объединений обсуждаются в п.0.5, спецификация перечислимого типа - в п.0.6; описания сопределяющими тип именами typedef обсуждаются в п. 0.9. -23-

Описатели

Входящий в описание список описателей представляетсобой последовательность разделенных запятыми описателей,каждый из которых может иметь инициализатор. список _ описателей: инициализируемый _ описатель инициализируемый _ описатель, спи - сок _ описателей инициализируемый _ описатель: описатель инициализатор необ Инициализаторы описываются в п.0.6. Спецификаторы и описанияуказывают тип и класс памяти объектов, на которые ссылаютсяописатели. Описатели имеют следующий синтаксис: описатель: идентификатор (описатель) * описатель описатель () описатель [ константное - выражение ] необ Группирование такое же, как и в выражениях.

Смысл описателей

Каждый описатель рассматривается как утверждение того,что когда конструкция той же самой формы, что и описатель,появляется в выражении, то она выдает объект указанного типаи указанного класса памяти. Каждый описатель содержит ровноодин идентификатор; это именно тот идентификатор, который иописывается. Если в качестве описателя появляется просто идентифика-тор, то он имеет тип, указываемый в специфицирующем заго-ловке описания. Описатель в круглых скобках идентичен описателю безкруглых скобок, но круглые скобки могут изменять связи всоставных описателях. Примеры смотри ниже. Представим себе описание t di где t - спецификатор типа (подобный int и т.д.), а di - опи-сатель. Предположим, что это описание приводит к тому, чтосоответствующий идентификатор имеет тип... t, где "..."пусто, если di просто отдельный идентификатор (так что тип х -24- в int х просто int). Тогда, если di имеет форму *d то содержащийся идентификатор будет иметь тип... указательна t. Если di имеет форму d () то содержащийся идентификатор имеет тип... функция, возвра-щающая t. Если di имеет форму d [ константное _ выражение ] или d [ ] то содержащийся идентификатор имеет тип... массив t. В пер-вом случае константным выражением является выражение, значе-ние которого можно определить во время компиляции и котороеимеет тип int. (точное определение константного выражениядано ниже). Когда несколько спецификаций вида "массив из"оказываются примыкающими, то создается многомерный массив;константное выражение, задающее границы массивов, можетотсутствовать только у первого члена этой последователь-ности. Такое опускание полезно, когда массив является внеш-ним или формальным и его фактическое определение, котороевыделяет память, приводится в другом месте. Первое констант-ное выражение может быть опущено также тогда, когда за опи-сателем следует инициализация. В этом случае размер опреде-ляется по числу приведенных инициализируемых элементов. Массив может быть образован из элементов одного изосновных типов, из указателей, из структур или объединенийили из других массивов (чтобы образовать многомерный мас-сив). Не все возможности, которые разрешены с точки зренияуказанного выше синтаксиса, фактически допустимы. Имеютсяследующие ограничения: функции не могут возвращать массивыили функции, хотя они могут возвращать указатели на такиевещи; не существует массивов функций, хотя могут быть мас-сивы указателей на функции. Аналогично, структуры или объе-динения не могут содержать функцию, но они могут содержатьуказатель на функцию. В качестве примера рассмотрим описание -25- int i, *ip, f (), *fip (), (*pfi)(); в котором описывается целое i, указатель ip на целое, функ-ция f, возвращающая целое, функция fip, возвращающая указа-тель на целое, и указатель pfi на функцию, которая возвра-щает целое. Особенно полезно сравнить два последних описа-теля. Связь в *fip () можно представить в виде *(fip ()), такчто описанием предполагается, что в выражении требуетсяобращение к функции fip и последующее использование косвен-ной адресации для выдачи с помощью полученного результата(указателя) целого. В описателе (*pfi)() дополнительныескобки необходимы, поскольку они точно так же, как и в выра-жении, указывают, что косвенная адресация через указательвыдает функцию, которая затем вызывается; эта вызваннаяфункция возвращает целое. В качестве другого примера приведем описание float fa [17], *afp [17]; в котором описывается массив чисел типа float и массив ука-зателей на числа типа float. Наконец, static int х3d [3][5][7]; описывает статический трехмерный массив целых размером3*5*7. Более подробно: х3d является массивом из трех элемен-тов; каждый элемент является массивом пяти массивов; каждыйпоследний массив является массивом из семи целых. Каждое извыражений х3d, х3d [ i ], х3d [ i ][ j ] и х3d [ i ][ j ][ k ] может разум-ным образом появляться в выражениях. Первые три имеют тип"массив", последнее имеет тип int.

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: