Лекція №1. Директиви препроцесора. Багатомодульне програмування

Содержание

Слайд 2

Директиви препроцесора. Багатомодульне програмування Мета роботи Отримати практичні навички застосування директив

Директиви препроцесора. Багатомодульне програмування
Мета роботи
Отримати практичні навички застосування директив

препроцесора, насамперед у створенні макросів, умовної компіляції, створенні багатомодульного проекту.
Директиви препроцесора починаються з символу "#" і виконуються під час 1-ї фази компіляції. Результат виконання потім компілюється, але може бути виведений в stdout або у файл за допомогою опцій компілятора.
Слайд 3

Директива #include Ця директива наказує препроцесору помістити на її місце вміст

Директива #include
Ця директива наказує препроцесору помістити на її місце вміст іншого

файлу. Синтаксис директиви
#include <имя_файла>
или
#include "имя_файла".
Якщо ім'я_файлу не є повним ім'ям, в першому випадку пошук відбувається тільки в межах специфікованих каталогів включаючих файлів. У другому випадку спочатку проглядається поточний каталог.
Слайд 4

Директива #define Директива #define визначає підстановку в тексті програми. Вона використовується

Директива #define
Директива #define визначає підстановку в тексті програми. Вона використовується для

визначення:
- символічних констант:
#define ім'я_текст підстановки
(всі входження імені замінюються на текст підстановки);
- макросів, які виглядають як функції, але реалізуються підстановкою їх тексту в текст програми:
#define ім'я (параметри текст_постановки;
- символів, керуючих умовної компіляцією. Вони використовуються разом з директивами #i fdef і #i fndef. Формат:
#define ім'я Приклади:
#define VERSION I
#define VASIA " Василь Іванович "
#define MAX(х,у) ((x)>(y) ? (x) : (y))
Слайд 5

Імена рекомендується записувати великими літерами, щоб візуально відрізняти їх від імен

Імена рекомендується записувати великими літерами, щоб візуально відрізняти їх від імен

змінних і функцій. Параметри макросу використовуються при макропідстановці, наприклад, якщо в тексті програми використовується виклик макросу y = MAX (suml,. sum2); він буде замінений на
у = ((suml)>(sum2)? (suml):(sum2));
Відсутність круглих дужок може призвести до неправильного порядку обчислення, оскільки препроцесор не оцінює текст який вставляється з точки зору синтаксису. Наприклад, якщо до макросу #deflne sqr (x) (х * х) звернутися як sqr (y + l), в результаті підстановки вийде вираз (у + 1 * у + 1).
Директиви #undef видаляє оголошену макропідстановку.
Слайд 6

Умовна компіляція Можна вибірково компілювати частини файлу. Синтаксис директиви умовної компіляції

Умовна компіляція
Можна вибірково компілювати частини файлу. Синтаксис директиви умовної компіляції наступний:
#if

вираз_1
// ця частина файлу компілюється, якщо вираз_1 істинний
#elif вираз_2
// я частина файлу компілюється, якщо вираз_1 помилково, а
// вираз_2 істинно
...
#else
// ця частина файлу компілюється, коли всі вирази помилкові
#endif
Директиви #elif і #else можуть бути опущені.
Слайд 7

Приклад. Просте виключення секції коду. #if 0 // виключена секція коду

Приклад. Просте виключення секції коду.
#if 0
// виключена секція коду
#endif
Значення виразів

в директивах #if і #elif повинні бути цілими константами. У виразах не можна використовувати операцію sizeof.
У якості вираження в директивах #if і #elif можна використовувати оператор defined. Він перевіряє, чи був визначений макрос.
Приклад. Вибір між секціями коду.
#if defined(DEBUGGING)
space = 1000;
#else
space = 10;
#endif
Директиви #ifdef і #ifndef є скороченням для директив
#if defined і #if! defined відповідно.
Слайд 8

Приклад. Запобігання багаторазової трансляції заголовка sample.h. #ifndef __SAMPLE_H__ #define __SAMPLE_H__ //

Приклад. Запобігання багаторазової трансляції заголовка sample.h.
#ifndef __SAMPLE_H__
#define __SAMPLE_H__
// тут зміст

файлу
#endif
Якщо файл sample.h виявиться багаторазово включеним у вихідний код програми, то при такому "обрамленні" його вмісту буде відтранслювувати лише перше входження заголовного файлу.
Зауваження. В Visual C ++ та ж мета досягається застосуванням директиви
#pragma once.
Директива #error
Директива #error викликає під час компіляції повідомлення про помилку.
#error повідомлення_про_помилку
Слайд 9

Приклад. Забезпечення правильності параметрів компіляції. #if !defined(__cplusplus) #error Цей файл повинен

Приклад. Забезпечення правильності параметрів компіляції.
#if !defined(__cplusplus)
#error Цей файл повинен компілювати

в режимі С ++
#endif
Повідомлення може містити ідентифікатори макросів, які будуть розширені препроцесором. Директива зазвичай застосовується, коли не було визначено необхідний макрос.
Директива #line
За допомогою директиви #line можна змінити внутрішній лічильник рядків компілятора і ім'я компільованого файлу. Вона має такий вигляд
Слайд 10

#line номер_рядка ["ім'я_файлу"] Директива #pragma Директива #pragma дозволяє впливати на процес

#line номер_рядка ["ім'я_файлу"]
Директива #pragma
Директива #pragma дозволяє впливати на процес і результат

компіляції. Ось кілька опцій для компілятора Visual C ++.
#pragma hdrstop - наказує компілятору не включати подальшу інформацію в предкомпілірованний заголовок;
#pragma once - наказує компілятору лише одного разу включати даний заголовний файл в програму;
#pragma warning - вибірково дозволяє або пригнічує попереджувальні повідомлення.
Слайд 11

Завдання Ввід-вивід елементів масиву та вирішення завдання оформити у вигляді макросів

Завдання
Ввід-вивід елементів масиву та вирішення завдання оформити у вигляді

макросів та розмістити їх в окремому модулі
Контрольний приклад
В матриці найти суму першого рядка, відсортувати другий рядок за збільшенням, а третій за зменшенням. Оформити кожну підзадачу у вигляді макросу.
Розв’язок
Головний файл (містить функцію main)
#include
using namespace std;
#include "myHeader.h"
Слайд 12

#define N 3 #define M 5 void main() { int mas[N][M]={9,3,6,23,21,

#define N 3
#define M 5
void main()
{
int mas[N][M]={9,3,6,23,21,
4,5,6,4,51,
4,6,24,23,24};
cout<<"Nachalnije dannie\n";
outmatr(mas,N,M);
#define cmp >
# if

defined (cmp)
sortmas(mas[1],M);
#else
cout<<"error";
Слайд 13

#endif #define MES "sort \">\" 2-ja stroka" cout outmas(mas[1],5); #define cmp

#endif
#define MES "sort \">\" 2-ja stroka"
cout<outmas(mas[1],5);
#define cmp <
#define MES "sort \"<\"

3-ja stroka"
# if defined (cmp)
sortmas(mas[2],M);
#else
cout<<"error";
#endif
cout<
Слайд 14

outmas(mas[2],5); cout int sum; SUM(mas[0],5,sum); cout cout outmatr(mas,N,M); cin.get(); } Файл

outmas(mas[2],5);
cout< int sum;
SUM(mas[0],5,sum);
cout<<"Summa 1-oj stroki = "<cout<<"Rezultat:"< outmatr(mas,N,M);
cin.get();
}
Файл “myHeader.h”
//---------------------------------------------------------------------------
#ifndef _MY_HEADER_
#define _MY_HEADER_
#define MES "ne

sort"
#define cmp ==
Слайд 15

#define sortmas(mas,n) { for (int i=0;i for (int j=0;j if(mas[j] cmp

#define sortmas(mas,n) { for (int i=0;i for (int j=0;j if(mas[j] cmp

mas[j+1])
{ mas[j]=mas[j]+mas[j+1]; \
mas[j+1]=mas[j]-mas[j+1]; \
mas[j]=mas[j]-mas[j+1];}; \
}
#define outmas(mas,n) { for (int i=0;i cout<<'\t'<