Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

— пространства имен;

— директивы препроцессора;

— комментарии.

В заголовочный файл нет смысла включать определения функций и данных.

Пример. Заголовочный файл pr. h — нет определений функций и данных, а только объявления

#include <iostream. h>

typedef float REAL; //определения типов

extern const double PI; //объявление константы

extern int i; //объявление данных ни в коем случае не инициализировать

REAL S(REAL R); //объявления функций

REAL S(REAL a, REAL b);

Файл pr. cpp — в нем есть определения функций и данных

#include <stdafx. h>

#include "pr. h"

int i=0; //определение данных и констант и их инициализация

const double PI = 3.1415926;

REAL S(REAL R) //определение функции

{

++i;

return R*R*PI;

}

REAL S(REAL a, REAL b) //определение функции

{

++i;

return a*b;

}

Файл m. cpp:

#include <stdafx. h>

#include "pr. h"

void main(void)

{

REAL a=2;

cout << S(a);

cout << S(3,4);

cout << "Площадь считали " << i << " раз" << endl;

}

Для того, чтобы переменная или константа были видны во всех модулях, необходимо определить ее как глобальную в одном файле *.cpp, а в заголовочном файле поместить ее объявление (со словом extern) и без инициализации.

Имя файла должно соответствовать соглашениям операционной системы и может состоять либо только из имени файла, либо из имени файла с предшествующим ему маршрутом. Если имя файла указано в кавычках, то поиск файла осуществляется в соответствии с заданным маршрутом, а при его отсутствии в текущем каталоге. Если имя файла задано в угловых скобках, то поиск файла производится в стандартных директориях операционной системы, задаваемых командой PATH.

НЕ нашли? Не то? Что вы ищете?

Директива #include может быть вложенной, т. е. во включаемом файле тоже может содержаться директива #include, которая замещается после включения файла, содержащего эту директиву.

Директива #include широко используется для включения в программу так называемых заголовочных файлов, содержащих прототипы библиотечных функций, и поэтому большинство программ на СИ начинаются с этой директивы.

Директива #include является простейшим средством обеспечения согласованности объявлений в различных файлах, она включает в них информацию об интерфейсе из заголовочных файлов. Заголовочные файлы обычно имеют расширение *.h и могут содержать:

— определения типов, встроенных функций, шаблонов, перечислений;

— объявления функций, данных, констант, имен, шаблонов;

— пространства имен;

— директивы препроцессора;

— комментарии.

Директива #define

Директива #define определяет подстановку в тексте программы.

Она используется для определения:

— символических констант:

#define имя текст_подстановки

#define VERSION 1

#define SK_SVETA 300000000

#define MYNAME "Вася"

cout << MYNAME; заменится на

cout << "Вася";

— макросов, которые выглядят как функции, но реализуются подстановкой их текста в текст программы.

#define MAX(x, y) ((x)>(y)?(x):(y)).

Команда программы:

z=MAX(2,4);

после выполнения фазы препроцессора будет выглядеть так

z=((2)>(4)?(2):(4));

А в результате выполнения в z занесется 4.

Отсутствие круглых скобок может привести к ошибке, например

#define SQR(x) (x*x)

при вызове

z=SQR(4+1)

Получим

z=(4+1*4+1), что неверно. Надо записывать со скобками

#define SQR(x) ((x)*(x))

— символов, управляющих условной компиляцией. Они используются вместе с директивами #ifdef и #ifndef.

Формат #define имя

#define DEBUG

Директивы условной компиляции

------------------------------

Директивы условной компиляции применяют для того, чтобы исключить

компиляцию отдельных частей программы. Это бывает полезно при отладке,

или выпуске программы с различными возможностями или разных платформ.

Формат #if:

#if константное_выражение

[#elif константное_выражение

.....

]

[#elif константное_выражение

.....

]

[#else

.....

]

#endif

Количество #elif произвольное.

int q=SQR(x);

#define DEBUG 1

#if DEBUG

cout << q << endl;

#endif

s=q+4;

#if DEBUG

cout << s << endl;

#endif

Если #define DEBUG 1 или лбое число не равное 0, то вывод на экран будет.

Если #define DEBUG 0, то вывода на экран не будет (0 = false).

Чаще используется директива #ifdef и #ifndef

int q=SQR(x);

#define DEBUG

#ifdef DEBUG

cout << q << endl;

#endif

s=q+4;

#ifdef DEBUG

cout << s << endl;

#endif

Если строка #define DEBUG есть, то вывод на экран будет.

Если строку #define DEBUG закоментарить, то вывода на экран не будет.

Директива #undef

#undef отменяет команду #define

int q=SQR(x);

#define DEBUG

#ifdef DEBUG

cout << q << endl;

#endif

s=q+4;

#undef DEBUG

#ifdef DEBUG

cout << s << endl;

#endif

Значение s на экран не выведется, а q выведется.

Заголовочный файл к каждому файлу с расширением *.cpp должен подключаться один раз. С этой целью его текст подключают между командами:

#ifndef __имяфайла_H__

#define __имяфайла_H__

.....тело заголовочного файла

#endif

Например, для Pr. h

Файл Pr. h

----------

#ifndef __PR_H__

#define __PR_H__

..... тело заголовочного файла pr. h

#endif

Описание переменных

-------------------

Общий вид оператора описания переменных:

[класс памяти] [const] тип имя [инициализатор];

[класс памяти] - auto, extern, static, register (extern по умолчанию)

(стр.30).

[const] - указывает, что значение переменной изменять нельзя - такую

переменную называют немодифиц. переменной.

[инициализатор] - служит для присвоения переменной начального значения.

short int a=1;

const char c = 'C';

char s, sf='f';

char t(54);

float x, m(3), c=0.22, sum;

Если тип инициализирующего значения не совпадает с типом переменной, то

производится преобразование типа по определенным правилам (стр.390).

Описание переменной, кроме типа и класса памяти, явно или по умолчанию

задает ее область действия. Класс памяти и область действия зависят не

только от собственно описания, но и от места размещения ее в тексте

программы.

Область действия идентификатора - это часть программы, в которой

его можно использовать для доступа к связанной с ним области памяти. В

зависимости от области действия переменная может быть локальной или

глобальной.

Если переменная опеределена внутри блока (блок ограничен {}), она -

локальная, область действия - от точки описания до конца блока.

Если переменная описана вне какого-либо блока, то она - глобальная,

область действия - файл, в котором она описана - от точки описания

до конца файла.

Лучше избегать использования глобальных переменных, поскольку функция,

не нуждающаяся в ней может испортить ее содержимое.

Класс памяти определяет время жизни и область видимости программного

объекта (в частности, переменной). Если класс памяти не указан явно, он

объявляется компилятором, исходя из контекста объявления.

Время жизни может быть постоянным (в течение выполнения программы) и

переменным (в течение выполнения блока).

Для задания класса памяти используются спецификаторы:

- auto - автоматическая переменная. Память под нее выделяется в стеке

каждый раз при выполнении оператора объявления. Освобождение памяти

происходит каждый раз при выходе из блока, в котором эта переменная

описана. Для глобальных переменных этот идентификатор не используется.

для локальных он устанавливается по умолчанию, поэтому задавать его

явно нет смысла.

- extern - означает. что переменная определяется в другом месте программы

(в другом файле или дальше по тексту). Используется для создания

переменных, доступных во всех модулях программы, в которых они объявлены.

Если присвоить значение переменной с extern, то extern игнорируется.

- static - статическая переменная.

Описывается внутри блока, является видимым только внутри блока, в

котором описан, но имеет глобальное время жизни, то есть создается

вначале работы программы и удаляется в конце. Начальное значение

задается при описании:

static int count = 1;

- register - аналогично auto, но память по возможности выделяется в

регистве микропроцессора. Если такой возможности у компилятора нет,

переменные обрабатываются как auto.

Класс памяти - auto, static, register, extern

Область действия - глобальная, локальная

Время жизни - глобальное, локальное

Файл a. h

----------

extern int w; //это еще не переменная - она только объявлена,

//но не описана

extern int z = 0; //extern игнорируется

//о. д.-глобальная, в. ж. - глобальное, кл. п - auto

#include <iostream. h>

#include <math. h>

#include "a. h"

//int z; //ОШИБКА - повторное объявление переменной z

//- она уже объявлена в a. h

int x=5; //о. д. - глобальная - видна ниже во всем файле

void a(void) // глобальная - видна ниже во всем файле

{

w = 2; //к w можно обращаться так как она уже объявлена

int x = 10; //о. д.-локальная, в. ж. - локальное, кл. п - auto

//эта строка выполняется при каждом входе в функцию

cout << x << endl; //10 ; 10

x++;

cout << x << endl; //11 ; 11

}

void b(void) // глобальная

{

static int x = 20; //о. д.-локальная, в. ж. - глобальное, кл. п. - static

//эта строка выполняется всего 1 раз при запуске программы

x++;

cout << x << endl; //21; 22

}

void c(void); //объявление функции c - о. д.-глобальная, в.ж. - глобальное

int w; //о. д.-глобальная, в. ж. - глобальное, кл. п - auto

//описание переменной объявленной ранее

void main(void)

{

cout << x << endl; //5

int x = 7; //о. д.-локальная, в. ж. - локальное, кл. п - auto

cout << x << endl; //7

{

int x = 8; //о. д. - локальная, в. ж.- локальное

int y = 3; //о. д. - локальная, в. ж.- локальное

static int s = 1; //о. д. - локальная, в. ж.- глобальное

cout << x << endl; //8

}

cout << x << endl; //7

a();

b();

c();

cout << x; // 7 - локальная

cout << ::x; //5 - глоб. переменная

a();

b();

c();

cin>>x;

}

void c(void)

{

cout << x << endl; //5 //это глобальная

}

Лекция 10.

Эволюция процесса разработки программного обеспечения

Исключения

-----------

При работе программы может возникнуть ошибка времени исполнения в

какой-либо функции. Функция может определить, что произошла ошибка,

однако функция не знает что делать в ответ на ошибку.

Пользователь этой функции (функция которая вызывала эту функцию

прямо или косвенно) знает как обработать ошибку, но не может ее обнаружить.

Для решения подобных проблем введено понятие исключения.

Фундаментальная идея заключается в том, что функция, обнаружившая

проблему, но не знающая как ее решить, генерирует исключение (throw)

в надежде, что вызвавшая ее функция (прямо или косвенно) сможет решить

возникшую проблему.

Функция, которая хочет решить проблему данного типа, может указать,

что она перехватывает (catch) исключение данного типа.

Такой стиль предпочтительнее других альтернативных:

1) прекратить работу программы;

2) возвратить значение означающее "ошибка" -

может не быть приемлемого значения;

3) возвратить допустимое значение и оставить программу

в ненормальном состоянии - вызывающая функция может не обнаружить,

что программа в ненормальном состоянии;

4) вызвать функцию, предназначенную для ошибочных ситуаций -

эта функция имеет один из вариантов 1-3.

Механизм обработки исключений позволяет отделить код обработки ошибок

от обычного кода, делая тем самым программу более читабельной.

Механизм обработки исключений позволяет обрабатывать ошибки в

том месте, где их лучше обрабатывать при данной структуре программы.

Подробнее об исключениях прочесть глава 7 (стр. 222-230).

throw исключение - сгенерировать исключение

try // начало контролируемого блока

{

//контролируемый блок - может произойти исключение

}

catch (тип_исключения) //отловить исключение типа тип_исключения

{

//действия, если произошло исключение типа тип_исключения

}

catch (тип2_исключения) ////отловить исключение типа тип2_исключения

{

//действия, если произошло исключение типа тип2_исключения

}

Если в контролируемом блоке произошло исключение на какой-либо команде,

то все команды за ней в контролируемом блоке выполняться не будут.

Пример:

Вычислить корни a*x^2+b*x+c=0.

void fun(const double a, const double b, const double c,

double & x1, double & x2)

{

double d=b*b-4*a*c;

if (d<0) then throw "Корней нет";

x1=(-b+sqrt(d))/(2*a);

if (d==0) then throw 0;

x2=(-b-sqrt(d))/(2*a);

}

void main (void)

{

double a, b, c;

double x1, x2;

cin >> a >> b >> c;

try

{

fun(a, b, c, x1, x2);

cout << endl << x1 << " " << x2;

}

catch (const char * p)

{

cout << p;

}

catch (const int i)

{

if (i==0)

cout << "Корень один x1=" << x1;

}

}

Переделать функцию, чтобы она находила не только вещественные корни,

но и комплексные, причем заголовок функции следующий:

void fun(const double a, const double b, const double c).

Пример: стек.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18