Слайд 1Перечисления (enum)
Перечислимый тип (enumerated type) служит для объявления символических имен,
представляющих целочисленные константы.
Можно сказать, что это тип данных, заданных
списком принадлежащих ему значений.
Назначение перечислимых типов заключается в том, чтобы повысить удобочитаемость программы.
Слайд 2Перечисления (enum)
Формат:
enum [ имя_типа ] { список_констант };
Имя типа
задается в том случае, если в программе требуется определять переменные
этого типа.
Компилятор обеспечивает, чтобы эти переменные принимали значения только из списка констант.
Слайд 3Перечисления (enum)
Константы должны быть целочисленными и могут инициализироваться обычным образом.
При отсутствии инициализатора первая константа обнуляется, а каждой следующей присваивается
на 1 большее значение, чем предыдущей:
enum Err { ERR_READ, ERR_WRITE, ERR_CONVERT};
Константам ERR_READ, ERR_WRITE, ERR_CONVERT присваиваются значения 0, 1 и 2 соответственно.
Слайд 4Перечисления (enum)
enum spectrum {red, orange, yellow, green, blue, violet};
enum spectrum
color;
enum {two = 2, three, four, ten = 10, eleven,
fifty = 50};
enum levels {low = 100, medium = 500, high = 2000};
enum Forms{ share, spere, cylinder};
enum {SUN, MON, TUES, FRI=5, SAT} day;
Имя
переменной
Имя
переменной
Слайд 5Перечисления (enum)
В общем случае перечислимые константы имеют тип int.
К перечислимой
переменной можно применять операции инкрементирования ++ и декрементирования – –.
Например,
for (color = red; color <= violet; ++color)
{
;
}
Слайд 6Перечисления (enum)
#include
#include
int main (void) {
enum month {january =
1, february, march, april, may, june,july, august, september, october, november,
december } aMonth;
int days;
printf("\n Enter the number of the month (1 - 12): ");
scanf_s("%d", &aMonth);
Слайд 7Перечисления (enum)
switch (aMonth) { // 31 день
case january:case march:case may:
case july:case
august:
case october:case december:
days = 31;
break;
// 30 дней
case april: case june:
case september: case november:
days = 30;
break;
Слайд 8Перечисления (enum)
case february:
days = 28;
break;
default:
printf("\n\t Wrong number of the month\n");
days
= 0;
break;
}
Слайд 9Перечисления (enum)
if (days)
printf("\n The number of days
of the month: %d\n", days);
if (aMonth == february)
printf("\n ... or 29 if it is a leap year\n");
printf("\n\n Press any key: ");
_getch();
return 0;
}
Слайд 10Объявление нового типа данных
typedef тип новое_имя [ размерность ];
Размерность может
отсутствовать.
typedef enum {FALSE, TRUE} boolean;
typedef unsigned int UINT;
typedef char Msg[100];
typedef
struct{
char fio[30];
int date, code;
float salary;} Worker;
Имя
нового типа
Имя
нового типа
Имя
нового типа
Имя
нового типа
Слайд 11Объявление нового типа данных
Введенное таким образом имя можно использовать таким
же образом, как и имена стандартных типов:
//две переменных типа unsigned
int
UINT i, j;
//массив из 10 строк по 100 символов
Msg str[10];
//массив из 100 структур
Worker stuff[100];
//переменная перечисляемого типа
boolean flag;
Слайд 12Директивы препроцессора
Препроцессор (англ. preprocessor) – программа, выполняющая предварительную обработку входных
данных для другой программы.
Препроцессор просматривает программу до компилятора и
заменяет в ней определенные сочетания символов (символические аббревиатуры) на соответствующие директивы.
Препроцессор отыскивает и подключает к программе необходимые файлы и может изменить условия компиляции.
Слайд 13Директивы препроцессора
Строки, начинающиеся со знака # (перед которыми разрешены символы
пустого пространства), задают препроцессору инструкции-директивы.
Каждая директива препроцессора должна занимать отдельную
строку.
#include
#include
#include
Слайд 14Директивы препроцессора
Имеются следующие директивы препроцессора:
Слайд 15Директива #include
Используется для включения в исходный текст программы файлов, содержащих
прототипы стандартных функций и части исходных текстов программы.
Имя исходного
(подключаемого) файла должно быть заключено в двойные кавычки или угловые скобки.
Слайд 16Директива #include
#include
– в этом случае файл ищется в
каталогах среды – эта форма используется при подключении стандартных файлов
Си и С++;
#include ″Имя файла″
– в этом случае файл сначала ищется в текущем каталоге проекта, а потом уже в каталогах среды – такая форма используется при подключении файлов конкретного проекта.
Слайд 17Директива #include
Файлы, имена которых находятся в директивах #include, могут в
свою очередь содержать другие директивы #include. Они называются вложенными.
Количество
допустимых уровней вложенности у разных компиляторов может быть разным.
В стандарте С89 предусмотрено, что компиляторы должны допускать не менее 8 таких уровней.
Слайд 18Директива #define
Используется для описания макроопределений – текстовых строк, вставляемых препроцессором
вместо указанных имен (макрокоманд). Вставляемые фрагменты можно настраивать с использованием
специально задаваемых параметров.
Слайд 19Директива #define
#define [()]
– имя, используемое для идентификации
строки (макрокоманда);
– список идентификаторов, обозначающих заменяемые элементы строки
– может отсутствовать;
<Строка> – строка-макроопределение, заменяющая имя в тексте программы.
Слайд 20Директива #define
#define nil 0
// определяет замену идентификатора nil нулем
#define N
5
// определяет замену идентификатора N числом 5
int A[N][N];…
#define MSG
″Это строка - пример″
// определяет замену идентификатора // MSG заданной строкой
Слайд 21Директива #define
#define P(X) printf(″X равен %d.\n″,X)
/* определяет замену идентификатора P
с параметром X на строку вывода данного параметра */
P(alf) //printf(″alf
равен %d.\n″,alf)
#define MAX(X,Y) (X>Y?X:Y)
int main() {
int x=5, y;
y= MAX(x,2);
cout << y << endl;
cout << MAX (7,x) << endl;
return 0; }
Слайд 22Директива #define
Имена макросов обычно задаются с помощью букв верхнего регистра.
Когда в программе встречается имя макроса, используемые в его определении
формальные параметры заменяются теми аргументами, которые есть в программе.
Такого рода макросы называются макросами с формальными параметрами (макроопределениями с параметрами и макросами, напоминающими функции).
Слайд 23Директива #define
Формальные подстановки, выполняемые посредством #define, могут привести к неожиданным
ошибкам, например:
#define ABS(X) (X>0?X:-X)
void main()
{
int i,j; … i= ABS(j++);
// Ошибка!
j++ будет выполнено дважды
}
Слайд 24Директива #undef
Используется для отмены команды #define.
Формат команды:
#undef
После выполнения
этой команды замена идентификатора на строку прекращается.
#define TABLE_SIZE 100
int table1[TABLE_SIZE];
#undef
TABLE_SIZE
#define TABLE_SIZE 200
int table2[TABLE_SIZE];
Слайд 25Директивы условной компиляции
Директивы условной компиляции дают возможность выборочно компилировать части
исходного кода программы.
Этот процесс называется условной компиляцией .
При этом
используются две конструкции.
Слайд 26Директивы условной компиляции
#if
[#else
и команды препроцессора>]
#endif
Слайд 27Директивы условной компиляции
#if
#elif
[#else
]
#endif
Слайд 28Директивы условной компиляции
Если находящееся за директивой #if константное выражение истинно,
то компилируется следующие за #if операторы языка и команды препроцессора.
Константное выражение может быть задано через директиву #define.
Директива условной компиляции #else используется практически так же, как в обычном условном операторе языка С: if – else.
Слайд 29Директивы условной компиляции
Аналогично используются директивы #elif (else if).
Если константное выражение
в директиве #elif истинно, то будет компилироваться соответствующая последовательность операторов
программного кода. При этом другие выражения в директивах #elif проверяться уже не будут, в том числе директива #else.
Слайд 30Директивы условной компиляции
В соответствии со стандартом С89 у директив #if
и #elif может быть не менее 8 уровней вложенности.
При
вложенности каждая директива #endif, #else или #elif относится к ближайшей директиве #if или #elif.
Каждая директива #if сопровождается директивой #endif.
Слайд 31Директивы условной компиляции
#ifdef имя_макроса
последовательность операторов
#endif
Директива условной компиляции #ifdef означает «if
defined» (если определено).
Последовательность операторов будет компилироваться, если имя макроса
было определено ранее с помощью директивы #define.
Слайд 32Директивы условной компиляции
#ifndef имя_макроса
последовательность операторов
#endif
Директива условной компиляции #ifndef означает «if
not defined» (если не определено).
Последовательность операторов будет компилироваться, если имя
макроса еще не определено директивой #define.
В директивах #ifdef и #ifndef можно использовать #else или #elif.
Слайд 33Директивы условной компиляции
#ifdef TABLE_SIZE
int table[TABLE_SIZE];
#endif
#ifndef TABLE_SIZE
#define TABLE_SIZE 100
#endif
int table[TABLE_SIZE];
Слайд 34Директивы условной компиляции
#if TABLE_SIZE>200
#undef TABLE_SIZE
#define TABLE_SIZE 200
#elif TABLE_SIZE
50
#else
#undef TABLE_SIZE
#define TABLE_SIZE 100
#endif
int table[TABLE_SIZE];
Слайд 35Директивы условной компиляции
#if !defined TABLE_SIZE
#define TABLE_SIZE 100
#elif defined ARRAY_SIZE
#define TABLE_SIZE
ARRAY_SIZE
int table[TABLE_SIZE];
#endif
Слайд 36Директива #error
Заставляет компилятор прекратить компиляцию, используется в основном для отладки.
Когда встречается эта директива, то выводится сообщение об ошибке.
#error сообщение – об – ошибке
Заданное
сообщение об ошибке в двойные кавычки не заключается.
#if !define(MODEL)
#error Building model not defined
#endif
Слайд 37Директивы условной компиляции
#if defined(NEARPOINTERS)
space=farcoreleft();
#elif defined(FARPOINTERS)
space=coreleft();
#else
#error Unsupported memory model
#endif
Слайд 38Операторы препроцессора # и ##
Операторы # и ## применяются в
сочетании с директивой #define.
Оператор #, который обычно называют оператором превращения
в строку (stringize), трансформирует аргумент, перед которым стоит, в строку, заключенную в кавычки.
Оператор ##, называемый оператором склеивания (pasting), или конкатенации, конкатенирует две лексемы. Операция ## должна иметь два операнда.
Слайд 39Операторы препроцессора # и ##
#define str(x) #x
cout
"test";
#define glue(a,b) a ## b
glue(c,out)
Слайд 40Операторы препроцессора # и ##
#define CHAR_COD(c) ""#c""
int main (void) {
char
ch;
printf("\n Введите символ: ");
scanf("%c", &ch);
printf("\n %s \"%c\", его код
%d", CHAR_COD(Символ), ch, ch);
printf("\n\n ... Нажмите любую клавишу: ");
_getch();
return 0;
}
Слайд 41Операторы препроцессора # и ##
#define TWO_LEXEME(a,b) a ## b
#define CHAR_COD(c)
""#c""
int main (void) {
char ch;
printf("\n Введите символ: ");
scanf("%c", &ch);
if (!(ch
% 2))
printf("\n %s \"%c\", его код %d %s", \ CHAR_COD(Символ), ch, ch, TWO_LEXEME(" - четный","!"));
Слайд 42Операторы препроцессора # и ##
else
printf("\n %s \"%c\", его код
%d %s", \ CHAR_COD(Символ),ch, ch,
TWO_LEXEME(" -
не “, "четный."));
printf("\n\nНажмите любую клавишу: ");
_getch();
return 0;
}