Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Стадии и директивы препроцессорной обработки




Лекция №26. Препроцессорная обработка

Разбор программы poker

card one_hand[9]; // максимум 9 карт при раздаче

deck dk;

int i, j, k, fcnt = 0, sval[4];

int ndeal, nc, nhand;

Это переменные, размещаемые в памяти при входе в блок при выполнении main. Переменная one_hand – это массив из девяти элементов (наибольшего числа карт в одной руке). В нём содержаться розданные из колоды карты. Переменная dk представляет колоду и размещается автоматически. Число карт в одной раздаче хранится в переменной nc, а количество раздач содержится в переменной ndeal. Переменная fcnt служит счётчиком флешей. Массив sval содержит число карт одной масти у игрока.

do {

cout << “\nПо сколько карт раздаём? (от 5 до 9): “;

cin >> nc;

} while (nc < 5 | | nc > 9);

nhand = 52 / nc;

cout << “\nСколько раз играем? “;

cin >> ndeal;

Программа запрашивает количество карт в одной раздаче. Для продолжения пользователь должен ввести число от 5 до 9. Число раздач, допускаемое размером колоды (52 карты) и количеством карт в одной раздаче (nc), вычисляется и помещается в переменную nhand. Затем программа запрашивает, сколько раз вы хотите «сыграть» в покер, то есть сколько всего раздач необходимо осуществить (ndeal).

srand (time(null));

init_deck(dk);

print_deck(dk);

for (k = 0; k < ndeal; k += nhand) {

if ((nhand + k) > ndeal)

nhand = ndeal – k;

shuffle(dk);

Функция time() используется генератором случайных чисел для затравки. Переменная dk инициализируется и колода перетасовывается каждый раз при проходе основного цикла.

for (i = 0; i < nc * nhand; i += nc) {

for (j = 0; j < nc; ++j) // обнуление счётчика масти

sval[j] = 0;

deal(nc, i, one_hand, dk); // очередная сдача

for (j = 0; j < nc; ++j)

sval[one_hand[j].s]++; // увеличение счётчика масти

for (j = 0; j < 4; ++j)

if (sval[j] >= 5) // 5 или больше – это флеш

fcnt++;

}

Массив slav содержит количество карт каждой масти и инициализируется нулём при каждой сдаче. Функция deal() сдаёт карты в массив one_hand. Выражение one_hand[j].s является значением масти конкретной карты – например 0, если карта трефовая. Затем это выражение служит индексом массива slav, в котором подсчитывают масти. С помощью переменной fcnt считаются флеши, выпавшие во всех этих испытаниях. Так как число испытаний равно ndeal, вероятность флеша будет fcnt/ndeal.

 

План:

1. Стадии и директивы препроцессорной обработки;

1. Замены в тексте;

2. Включение текстов из файлов;

3. Макроподстановки средствами препроцессора.

 

 

В интегрированную среду подготовки программ на С++ или в компилятор языка как обязательный компонент входит препроцессор. Назначение препроцессора – обработка исходного текста программы до её компиляции.

Препроцессорная обработка в соответствии с требованиями стандарта языка С++ включает несколько стадий, выполняемых последовательно. Конкретная реализация транслятора может объединять несколько стадий, но результат должен быть таким, как если бы они выполнялись последовательно:

- все системно-зависимые обозначения (например, системно-зависимый индикатор конца строки) перекодируются в стандартные коды;

- каждая пара символов ‘\’ и “конец строки” убираются, и тем самым следующая строка исходного файла присоединяется к строке, в которой находилась эта пара символов;

- в тексте распознаются директивы препроцессора, а каждый комментарий заменяется одним символом пустого промежутка;

- выполняются директивы препроцессора и производятся макроподстановки;

- ESC-последовательности в символьных константах и символьных строках, например, ‘\n’ заменяются на их эквиваленты (на соответствующие числовые коды);

- Смежные символьные строки конкатенируются, т.е. соединяются в одну строку.

Знакомство с перечисленными задачами препроцессорной обработки объясняет некоторые соглашения синтаксиса языка. Например, становится понятным смысл утверждений: каждая символьная строка может быть перенесена в файле на следующую строку, если использовать символ ‘\’ или “две символьные строки, записанные рядом, воспринимаются как одна строка”.

Рассмотрим подробно стадию обработки директив препроцессора. При её выполнении возможны следующие действия:

· Замена идентификаторов (обозначений) заранее подготовленными последовательностями символов;

· Включение в программу текстов из указанных файлов;

· Исключение из программы отдельных частей её текста (условная компиляция);

· Макроподстановка, то есть замена обозначения параметризованным текстом, формируемым препроцессором с учётом конкретных параметров (аргументов).

Для управление препроцессором, т.е. для задания нужных действий, используются команды (директивы) препроцессора, каждая из которых помещается на отдельной строке и начинается с символа #. Определены следующие препроцессорные директивы:

à Директива #define имеет несколько модификаций. Они предусматривают определение макросов или препроцессорных идентификаторов, каждому из которых ставится в соответствие некоторая символьная последовательность. В последующем тексте программы препроцессорные идентификаторы заменяются на заранее запланированные последовательности символов.

à Директива #include позволяет включать в текст программы текст из выбранного файла.

à Директива #undef отменяет действие команды #define, которая определила до этого имя препроцессорного идентификатора.

à Директива #if и её модификации #ifdef, #ifndef совместно с директивами #else, #endif, #elif позволяют организовать условную обработку текста программы. Условность состоит в том, компилируется не весь текст, а только те его части, которые так или иначе выделены с помощью перечисленных директив.

à Директива #line позволяет выполнять нумерацией строк в файле с программой. Имя файла и начальный номер строки указываются непосредственно в директиве #line.

à Директива #error позволяет задать текст диагностического сообщения, которое выводится при возникновении ошибок.

à Директива #pragma вызывает действия, зависящие от реализации.




Поделиться с друзьями:


Дата добавления: 2014-01-06; Просмотров: 436; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.008 сек.