- •Алгоритм.
- •Множественный выбор switch.
- •Оператор do … while ( с постусловием ).
- •Do оператор ;
- •Оператор цикла for.
- •Использование операторов break и continue в циклах.
- •Функции ввода-вывода.
- •Общий вид программы.
- •Вложенные циклы.
- •Адреса и указатели.
- •Массивы.
- •Int a[10] ; // целочисленный вектор из 10 элементов.
- •Векторы.
- •Сортировка вектора.
- •Матрицы.
- •Строки.
- •Подпрограммы.
- •Директива препроцессора #define .
- •Области видимости.
- •Классы памяти.
- •Рекурсия.
- •Подготовка к зачету.
- •Структуры.
- •Int ball [4] ; // описание третьего поля – оценки.
- •Очередь.
- •Линейные списки.
- •Деревья.
- •Int n, k ; // ее размерности
- •Void print ( void ) // печать матрицы
- •Определение методов вне класса.
- •Частные и общие данные.
- •Конструктор.
- •Перегрузка операторов.
- •Неявный указатель *this.
- •Дружественные функции.
- •Класс множество.
- •Наследование.
- •Объекто-ориентированное программирование.
- •Список вопросов к экзамену.
- •Литература.
Директива препроцессора #define .
Мы уже сталкивались с директивами препроцессору #include для включения информации из другого файла в программу. При помощи директивы препроцессора #define можно задавать константы.
#define PI 3.14
При компиляции программы каждый раз вместо PI будет подставлено ее значение. Знак ; не ставится, т.к. это не оператор языка С. Использовать эту директиву можно для любых констант, даже для звукового сигнала ‘007’, и признака конца -‘\0’.
#define BEEP ‘007’
#define NULL ‘\0’
При чем использовать эти константы можно в любой подпрограмме, они являются глобальными.
Могут быть и такие макроопределения:
#define FMT “ x %d \n”
далее в программе к нему обращаются так:
printf (FMT, x ) ;
Макроопределения еще их называют - макросами – это текстовые подстановки, происходящие до компиляции программы. Вы заметили, что все макросы пишутся с большой буквы – это договоренность между программистами. Если видишь, что-либо написанное с большой буквы, ищи определение объекта как макроса в директиве препроцессора #define.
Хотя это требование не правило, если вы напишите с маленькой буквы, все будет работать.
Могут быть макроопределения и с параметрами:
#define SQR ( X ) X*X
далее в программе к нему обращаются так:
x=4 ; y=12 ;
z1= SQR(x) ;
z2= SQR(y) ;
Могут быть и более сложные условные макросы:
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#define ABS (X) ( X < 0) ? -(X) : (X))
далее в программе к ним обращаются так:
y=2*MAX(a+b , r+c ) ;
z= ABS ((x-y)/2.) ;
Области видимости.
Рассмотрим программу из двух функций:
#include …
void func (int *a, float b) // в скобках формальные параметры
{ int x, y ; // локальные переменные
…
}
main()
{
int x, y, z ; // y и z локальные переменные
float b ;
…
func(&x, b) ; // в скобках фактические параметры
}
Локальные переменные в каждой функции являются внутренними и не известны другой функции. Вся связь между подпрограммами осуществляется через параметры. Язык С допускает наличие переменных известных во всех функциях, они называются - глобальными.
Сделаем переменную b из предыдущего примера глобальной.
#include …
float b ; // описание глобальной переменной
void func (int *a ) // в скобках формальные параметры
{ int x, y ; // локальные переменные
…
x=b ; // использование глобальной переменной
}
main()
{
int x, y, z ; // y и z локальные переменные
b++ ; // использование глобальной переменной
…
func(&x ) ; // в скобках фактические параметры
}
Макросы принципиально отличаются от глобальных переменных, т.к. это подстановки происходящие до компиляции, а не работа с переменными способными произвольно изменять свои значения в каждой из функций.
Классы памяти.
Каждая переменная имеет тип, кроме того каждая переменная принадлежит к некоторому классу памяти. До использования подпрограмм мы не задумывались об этом, т.к. пользовались всегда одним классом памяти – автоматическим. Вообще существует 4 класса памяти.
extern |
Внешний |
auto |
Автоматический |
static |
Статический |
register |
регистровый |
Классы памяти позволяют определить:
- какие функции имеют доступ к каким переменным, т.е. определяют области
видимости;
- как долго переменные находятся в памяти.
Рассмотрим каждый класс памяти.
Auto
По умолчанию все переменные, описанные внутри функции, являются автоматическими. Эти переменные локальные.
main()
{
int x, y ; одно и то же auto int x, y ;
…
}
Аuto иногда пишут специально, чтобы не искать описание объектов вне функции.
Переменные с теми же именами, используемые в других функциях, физически другие, нет никакой связи между ними.
Автоматическая переменная возникает при вызове функции, и исчезает при ее окончании, ее ячейка может быть использована для других целей.
Exetrn
int a ;
main()
{ extern int a ; // a – внешняя, глобальная переменная.
…
x=a*b ;
…
}
Будет то же самое, если вообще не описывать переменную а в main, но когда явно описано, что переменная extern, то понятно, что она глобальная и описана выше.
Внешние переменные известны всем функциям, и не исчезнут, пока не закончит работу вся программа.
Static
Статические переменные локальные, т.е. видны только из одной функции, но они не исчезают при окончании работы функции до окончания работы всей программы. Компилятор хранит их значения от одного вызова до другого.
Рассмотрим простой пример иллюстрирующий работу статической переменной.
main()
{ int i ;
for ( i=1 ; i<=3 ; i++)
{ printf (“ i=%d\n”, i) ;
ff() ;
}
}
void ff(void)
{ int a=1 ;
static int b=1 ;
printf(“a=%d b=%d\n”, a++, b++) ;
}
печать результатов будет такой:
i=1
a=1 b=1
i=2
a=1 b=2
i=3
a=1 b=3
Автоматическая переменная а при каждом вызове инициализируется заново, а статическая переменная b только при первом вызове функции. Такие переменные удобно использовать, когда нужно накапливать сумму при многократном обращении к подпрограмме.
Могут быть и внешние статические переменные.
register
Регистровые переменные хранятся на регистрах центрального процессора, где доступ и работа с ними быстрее, чем в памяти. С такими переменными мы работать не будем.
Рекомендация: старайтесь использовать автоматические переменные и передавать информацию в
функции через параметры. Неосторожное использование глобальных переменных
порождает большие ошибки.
