GCC - The Complete Reference (537669), страница 23
Текст из файла (страница 23)
Оператор затем воспринимает адрес указателя типа чоЫ в качестве допустимого адреса для перехода Ошпр). Указатель не может быть корректно использован для перехода на адрес метки внутри другой функции. 102 Часть Н. ИспользоааниеСборного Компилятора Благодаря тому, что в операторе досо может быть использовано любое выражение, возвращающее чоЫ-указатель, можно создать массив адресов меток и переходить на них по индексу: чойд '1ое[] = ( йй1аЬе11, йй1аЬе12, йй1аЬе13, йй1аЬе14 ); доео *1ое[1); Локально объявляемые метки Есть возможность такого объявления метки, что она будет определена лишь в границах определенной области действия.
Ключевое слово 1аЬе1 используется в начале области действия (например, за открываюшей операционной скобкой "(") для объявления локальной метки, действуюшей только в пределах этой области. Вот пример программы, демонстрирующей ибъявление и использование двух локальных меток: /* 1ое1аЬе1.е */ $3.пе1пде <всо1о. Ь> 1пс ва[п(1пс агде,еЬаг *агдч[)) ( 1пс поппе = О/ 1аЬе1 гевеаге; 1аЬе1 г[п1ввеаг гевсагс: рг1пег("поппе=те)Чп",поппе) 15(поппе > 5) доео Е1п1ввеау поппе++у доео гевсагсг т[паввео: поппе += 10/ ) геспгп(0)г ) Можно объявлять несколько меток (через запятую): 1аЬе1 гевеаге, г1п1ввеоу Использование такого рода меток может быть полезным внутри кода, расширяемого по макроопределению.
Добавляя операционные скобки для отделения области действия можно избежать пересечения областей в случае применения разных меток с одинаковыми именами внутри одной функции. Составные выражения в левой части оператора присваивания, ~ча!це (~ча!ие Ехргеыюпя) Составные выражения могут использоваться с левой стороны оператора присваивания (это и есть "1ча[ие", то есть "значение левой части"). Это справедливо для того случая, когда доступен адрес результата составного выражения.
Обычной формой Глава 4. Компиляция программ на языке С 1 03 1>а)ие является имя переменной. В следующем примере переменная а — имя распо- ложения в памяти, куда будет записано числовое значение 5: В другой форме своего применения Ьа)ие в действительности оказывается на правой стороне оператора, но остается самим собой, потому что правая сторона присваивания в этом случае является адресом памяти, а не значением. В примере переменная е используется как Ьа1ие; рег = ве; При известных особых обстоятельствах составные выражения также могут использоваться как 1ча)ие. Вот список свойств и правил для составления выражений Ьа(ие: ° Составное выражение, может использоваться как Ьа1ие если может быть получен адрес последнего члена этого выражения.
В примере показано два равносильных оператора: (Еп(), Ь) = 10( гп(), (Ь = 10); ° Имеется воэможность получения адреса составно(о выражения. Его адресом будет адрес последнего члена выражения. В этом примере в рег будет записан адрес переменной Ь (иначе говоря, Ьа(ие Ь): рсг = Е(вп(), Ь); е Можно применять !га)ие как условные выражения в случае, если оба варианта выбора являются корректными выражениями Ьа1ие. В этом примере оператор присваивает Ь значение 100, и оно больше чем константа 5. При этом с присваивается значение 100; ((е > 5) т Ь ° с) = 100( ° Ьа)ие поддерживает приведение к другому типу.
В предлагаемом примере указатель сЬрег типа сЬаг приводится к 1пг типа указателю, в который записывается абсолютный адрес константы "894": снег *свркгк (1пс) свргг = 894; Макроопределения с переменным количеством аргументов (Масгоь а~тп ЧапаЫе Агдовепй) Существует два способа для создания макросов с переменным количеством аргументов, потому что один иэ них — собственное расширение ССС, а другой, несколько отличающийся способ, соответствует стандарту "! Ю С99". Далее — пример, использующиий метод стандарта )ВО: яае11пе еггопе(гас, ...) Йрг1пс(вссегг,еее, чА ИМЯ ) Любой список аргументов, указываемый после й(яв, будет подстанавливаться вместо чл Анан везде, где бы он не встречался в теле макроопределения.
При ис- 104 Часть П. Использование Сборного Компилятора пользовании синтакса О)ЧО С тот же макрос будет определяться следующим обра- зом: Впееьпе еггопг(сшс, агде ... ) Ерг1пе(веоегг, гве, агде) Более подробно о макроопределениях и расширениях макросов смотрите в главе 3. Строки (Йп пят) Переход на новую строку может вставляться в строку литер без использования езсаре-последоваглельлос)пи "1п". Он может передаваться прямо из исходного кода.
Два предлагаемых примера строковых литералов всг1 и всгд идентичны: сьаг *всг1 -" "А всг1пд опмпгио 11пев" сваг ~вега = "А аег1пд оп Еео 11пев" Езсаре-код "1е" соответствует специальной литере "пяс" кодировки АБС)!. Последовательность "ме" также может использоваться в строковых литералах. Как обычно, обратная наклонная черта в конце строки исходного кода объединяет зту строку с последующей: сваг *вега = "тц1е есг1пд и111 1 Ье Зоъпеа 1пео опе зьпе."г Это вполне соответствует стандарту языка С. Расширение О)ЧО С упрощает неудобно строгое правило языка Со том, что при объединении строк символ перехода строки лолжен следовать сразу же за обратной наклоннсй чертой.
ОСС разрешает оставлять любое количество пробелов после обратной наклонной черты. Лишние пробелы убираются компилятором и строки объединяются, но при атом препроцессор выдает предупредительное сообщение. Арифметические действия над указателями (Ро~п1ег Апйвебсь) Для указателей на данные (то(д ро(п(егз) и указателей на функции (гипс(!оп ро!п(егз) поддерживаются операции сложения и вычитания. Указатель инкрементируется или декрементируется с учетом размера того типа, на который он указывает.
В ОСС указатели на функции и данные инкрементируется или декрементируется на 1. Это является результатом того, что оператор вйвеой для указателя всегда возвращает 1. Опция -)тройпвег-агйе)з специально используется для вывода предупредительных сооб)цений об использовании этого расширения.
Операторы Байсп и Саяе Диапазон значениий может назначаться с помощью троеточия. Вот пример стандартного ("АМБ! С") способа выбора из четырем значений для обычного оператора саве: Глава 4. Компиляция программ на языке С 105 саве 8: саве нз севе 10з саве 11: То же самое можно написать с использованием троеточия: саве 8 ... 11: Важно отметить, что троеточие должно быть окружено пробелами. Это необходимо, чтобы предотвратить ошибку работы синтаксического разделителя (рагзег епог), состоящую в том, что точки могут быть восприняты в качестве десятичного разделителя константы.
Также и пересечение диапазонов в операторах саве (как и дублирование простых констант в них) приведет к выдаче компилятором сообшення об ошибке: саве 8 ... 19ю саве 12 ... 32: г г овивка! Этот способ особенно удобен при указании оператору саве диапазона буквенных констант: саве 'а' ... 'ш': Создание имени определяемого типа (Туреде1 йаае Сгеабоп) Ключевое слово суребеЕ может использоваться для создания имени для типа данных результата ныражения.
Определенное таким образом имя может использоваться для объявления или приведения типа переменных, они будут иметь тот же тип, зто и результат выражения. Новое имя типа определяется так: СуреаеЕ лате евхневвяол> Например, следующие операторы определяют вша11кеа1 как числовой тип с пламющей точкой и 1акдекеа1 как нешественное число с двойной точностью боиЬ1е: Суресее вше11сее1 = О.ОЕ > СуресеЕ 1асдесее1 = О.О г Эти новые имена могут в дальнейшем использоваться для объявления переменных предстанляемого нми типа. В следующем примере операторов (стоящих дальше 8 коде той же программы) кеа11 объявляется как Е1оас и кеа12 как йоцЬ1е: вше11сее1 сее112 1асдесеа1 сеа12г Одним из удобных мест использования этого расширения являются макроопрезеления, которые должны применяться к нескольким типам данных.
Следующий накрос не получает предварительных сведений о типах аргументов, переменные в хакросе получают тип аргументов и могут поэтому обмениваться с ними своим знамнием: 1 06 Часть (!. Использование Сборного Компилятора ()дее1пе амар <а, Ь) (( суреоег ер = аг х ср елыр = а; а=Ь/ Ь = Ееыр) )) Для определения имени локального типа ср используется тип первого аргумента. Локальная переменная сеыр обьявляется как локальное временное расположение данных типа ср, что дает возможность обмена значениями двум переменным независимо от их типов. Ссылки на типы переменных (Турео1 йе1егепсеь) Ключевое слово суреой возвращает тип выражения. Оно используется подобно оператору здхеог, но в отличие от него возвращает тип вместо размера.
Вот — пример использования: сЬаг *спрсг/ суреог (*сьрег) сЬ/ Еуреог (сЬ) *сЬрсг2/ Суреог (слрег) сЬраггау[10]г гуреев (*сЬрсг) сЬаггау(10]) Суреог (сЬ) сЬаггау2(10]г // Указатель на сЬаг // тип сЬаг // Указатель на сЬаг // 10 указателей на сЬаг // 10 переменных типа сЬах // 10 переменных типа сЬаг сЬаг Еппсю / Еуреог (гипс) гезуа1/ Функция йппс ( ) возвращает результат типа сйаг, поэтому выражение суреой объявляет переменную с именем гесуа1 типа сЛаг. В выражениях суреой вы можете использовать непосредственно имена типов. Следующий пример содержит два равносильных оператора: сЬаг *сЬагрегг Еуреог (сЬаг *) сЬагрегг Применение суреой дает возможность создавать макроопределения, используемые для объявления переменных. В следующем примере определяется макрос, используемый затем для создания двух массивов — массива десяти переменных с]опЬ1е, и массива десяти переменных й1оаел В этом примере сЬрсг объявляется как указатель (ро!0(ег) на переменную типа сйаг.
Используя суреой для определения типа, на который указывает сьрсг, сь объявляется соответственно как переменная типа сйаг. И наоборот, используя тип данных переменной сЬ, объявляется сЬрег2 как указатель (ро(п(ег) на переменную типа сйаг. Переменная сЬраггау объявляется как массив из десяти указателей на данные типа сйаг. Объявление массива сЬаггау основывается на типе указателя на переменную сЬрсг, таким образом, являясь объявлением массива десяти переменных сйаг. Другой массив десяти переменных типа сйаг основывается на типе переменной с именем сЬ.
В следующем примере объявляется переменная того же типа, что и результат, возвращаемый функцией: Глава 4. Компиляция программ на языке С 107 йеее(пе аггау(суре, в1хе) гуреев(суре(в1хе) ) аггау(сспЬ1е, 10) дЬ1аггаук аггау(е1сае, 10) е1еаггау( Приведение типов объединения (Оп~оп Сай~ад) Тип элемента данных объединения (цп)оп) может быть применен для приведения к нему всего объединения в целом.