
- •Виды специализированных языков:
- •Особенности языка Си
- •Особенности других языков
- •Использование указателей при обращении к эелементам массивов
- •Int array[25]; // array эквивалентно &array[0]
- •Области действия и области видимости переменных, классы памяти, локальные, глобальные и статические переменные.
- •Операции языка Си
- •Операция преобразования типов
- •Операторы цикла
- •Особенности применения оператора for
- •Операторы условных и безусловных переходов
- •If (условие) оператор_1; else оператор_2;
- •Особенности применения
- •Int type; /* признак компонента */
- •Определение объектов и типов
- •Инициализация данных
- •Объявление функций
- •Аргументы функции main( )
Int type; /* признак компонента */
union /* перечисление компонент */
{ double radius; /* окружность */
double a[2]; /* прямоугольник */
double b[3]; /* треугольник */
} geom_fig;
} fig1, fig2 ;
В общем случае каждый объект типа figure будет состоять из трех компонентов: area, perimetr, type. Компонент type называется меткой активного компонента, так как он используется для указания, какой из компонентов объединения geom_fig является активным в данный момент. Такая структура называется переменной структурой, потому что ее компоненты меняются в зависимости от значения метки активного компонента (значение type).
Отметим, что вместо компоненты type типа int, целесообразно было бы использовать перечисляемый тип. Например, такой
enum figure_chess { CIRCLE,
BOX,
TRIANGLE
} ;
Константы CIRCLE, BOX, TRIANGLE получат значения соответственно равные 0, 1, 2. Переменная type может быть объявлена как имеющая перечислимый тип :
enum figure_chess type;
В этом случае компилятор СИ предупредит программиста о потенциально ошибочных присвоениях, таких, например, как
figure.type = 40;
Определение объектов и типов
При объявлении простой переменной, структуры, смеси или объединения, а также перечисления, описатель – это простой идентификатор. Для объявления указателя, массива или функции идентификатор модифицируется соответствующим образом: звездочкой слева, квадратными или круглыми скобками справа.
Однако надо помнить, что некоторые комбинации модификаторов недопустимы:
– элементами массивов не могут быть функции,
– функции не могут возвращать массивы или функции.
При инициализации сложных описателей квадратные и круглые скобки (справа от идентификатора) имеют приоритет перед звездочкой (слева от идентификатора). Квадратные или круглые скобки имеют один и тот же приоритет и раскрываются слева направо. Спецификатор типа рассматривается на последнем шаге, когда описатель уже полностью проинтерпретирован. Можно использовать круглые скобки, чтобы поменять порядок интерпретации на необходимый.
Для интерпретации сложных описаний предлагается простое правило, которое звучит как "изнутри наружу", и состоит из четырех шагов.
1. Начать с идентификатора и посмотреть вправо, есть ли квадратные или круглые скобки.
2. Если они есть, то проинтерпретировать эту часть и затем посмотреть налево в поиске звездочки.
3. Если на любой стадии справа встретится закрывающая круглая скобка, то вначале необходимо применить все эти правила внутри круглых скобок, а затем продолжить интерпретацию.
4. Интерпретировать спецификатор типа.
Примеры: int * ( * comp [10]) ();
6 5 3 1 2 4
В данном примере объявляется переменная comp (1), как массив из десяти (2) указателей (3) на функции (4), возвращающие указатели (5) на целые значения (6).
typedef double (* MATH)( );
MATH – новое имя типа, представляющее указатель на функцию, возвращающую значения типа double
MATH cos; – cos указатель на функцию, возвращающую значения типа double
Можно провести эквивалентное объявление double (* cos)( );
typedef char FIO[40] FIO – массив из сорока символов
FIO person; // = char person[40];