
- •3. Строение памяти. Системы счисления. Двоичная система счисления
- •8. Расширенные Бэкуса-Наура формы (рбнф), Способы записи синтаксиса языка: Диаграммы Вирта. Расширенные Бэкуса-Наура формы (рбнф).
- •12. Операторы выбора: оператор if, оператор switch. Операторы выбора.
- •1. Принципы объектно-ориентированного программирования. Основными свойствами ооп являются:
- •18. Создание собственных функций-манипуляторов.
- •1.Assign(const string& str);
- •31. Последовательные контейнеры.
12. Операторы выбора: оператор if, оператор switch. Операторы выбора.
Большинство операторов управления программы, основываются на проверки условий , определяющие какого рода действие необходимо выполнить. С++ поддерживает 2 типа оператора выбора: if и switch.
if if (выражение) оператор 1; else оператор 2;
Если выражение истина, то выполняется блок операторов следующих за if, иначе выполняется блок операторов следующих за else.
0<x<1 , чтобы записать (х>0)&&(x<1) switch (сравнение) выполняющий действия основывающий на сравнения значения со списком констант. При обнаружение совпадения выполнятся операторы ассоциированные с данным значением
switch >>> case 1 or case 2 or.... case n, если не найдено сравнение, то выполняется default.
switch (выражение) { case константа1: последовательность операторов break; case константа2: последовательность операторов break; ... default: последовательность операторов }
default - выполняется, если не найдено совпадений. Он не обязателен, если его нет, то в случае отсуствия совпадений ничего не выполняется. Когда обнаруживается совпадения оператора ассоциированного с соотвествующим case выполняется до тех пор, пока не встретится оператор brake. Оператор switch отличается от if, тем, что он может выполнять только операторы проверки строгого равенства. Не может быть 2ух констант в операторе switch имеющих одинаковое значение. Если в операторе switch используются символьные константы , то они автоматически преобразуются к целочисленным значениям.
13. Циклы в С++. Операторы передачи управления. Операторы цикла используются для организации многократно повторяющих вычислений. Любой цикл состоит из тела цикла т.е. тех операторов, которые выполняются несколько раз, начальных установок, модификации параметра цикла и проверки условия продолжение выполнения цикла. Проверка условия выполняется на каждой операции либо до тела цикла ( цикл и с предусловием ), либо после тела цикла ( цикл с постусловием ). Разница между ними состоит в том, что тело цикла с постусловием всегда выполняется хотя бы один раз, после чего проверяется нужно ли его выполнить еще раз. Проверка необходимости выполнения цикла с предусловием делается до тела цикла поэтому возможно, что он не выполнится ниразу. Стандартный вид цикла for следующий: for (инициализация; условие; увеличение) оператор; При выполнения цикла while сначала проверяется условие, если оно ложно, то цикл не выполняется и управление передается за тело цикла. Если условие истина, то выполняется тело цикла и снова проверяется условие. Цикл while ("пока") с предусловием; while (условие) инструкция; цикл do/while проверяет условие в конце т.е. этот цикл выполняется по крайней мере один раз Пример: является ли введенное с клавы число простым Операторы передачи управления.
BREAK - имеет два назначения: 1. Окончание работы оператора switch; 2. Принудительное окончание цикла минуя стандартную проверку условия.
Когда оператор break встречается в теле цикла, цикл немедленно заканчивается и к выполнению переходит на строку следующую за циклом. EXIT - вызывает немедленное окончание работы программы. Функция находится в заголовочном файле Функция exit() имеет след. вид: void exit (int статус); Она использует заголовочный файл stdlib.h
CONTINUE - осуществляет переход к следующей операции цикла, пропуская оставшийся код тела цикла
goto - оператор передачи управления на фрагмент программы помеченный меткой. Метка - это корректный индификатор завершаемый двоеточием.
14. Программные модули в С++. Процедуры и Рекурсия. Большинство программ, которые решают реальные практические задачи, представляют собой набор модулей, каждый из которых более управляем чем сложная программа, и выполняет свои функции. Модули в языке С++ называются функциями и классами. Обычно программы пишутся модулем объединения новых функций с функциями уже имеющимися в стандартной библиотеке. А так же классов, которые пишет сам программист с классами имеющимися в стандартной библиотеке. Стандартная библиотека обеспечивает широкий набор функций для выполнения математических расчетов, операций со строками, ввода ,вывода и других. Функции активизируются, т.е. начинают выполнять запроектированную задачу путем вызова функции. В вызове функции указывается ее имя и дается информация в виде аргументов, необходимая вызываемая функции для ее работы.
Процедуры и Рекурсия. Функция может и не возвращать значение, тогда в ее объявлении в качестве типа возвращального значения, следует указать void. Функция, не возвращающая значение, должна завершаться инструкцией return без указания значения, а может и не содержать return. void hello () // Функция не возвращает значения { // и не принимает ни одного параметра cout << " Hello, world!" << endl ; return ; { Вывоз процедуры: hello ();
Рекурсивное определение функции факториал дается следующим соотношением: n!=n*(n-1)!
В С++ есть 2 способа обращения к функции : вызов по значению и вызов по ссылке. Когда аргумент передается вызовом по значению, создается копия аргумента и она передается в вызываемой функции. Вызов по ссылке может ослабить защищенность программы, потому что вызываемая функция может их испортить. Ссылочный параметр - это псевдоним соответствующего аргумента. Что бы показать, что параметр передан по ссылке после типа указывается символ аперсант.
15. Определения функций. Локальные и глобальные переменные. Локальные и глобальные переменные. Внутри функции могут быть объявлены быть переменные, которые называются локальными. Их область видимости только внутри функции. Переменные, определенные вне тела функции называются глобальными. И они определены всюду , начиная с места определения и до конца файлов. Локальные переменные создаются каждый раз при входе в функцию и уничтожаются при выходе из нее. Таким образом значение сохраненные в локальных переменных пропадут после завершения работы функции. В различных функциях можно определять переменные с одним и тем же именем и это будут различные переменные. Так же можно объявлять в функциях переменные, имена которых совпадают с именами глобальных переменных. В этом случае будет создана новая локальная переменная, а изменять значение глобальной переменной с таким именем будет невозможно. Определения функций. Синтаксис определения функции в языке С++: возвращаемый_тип идентификатор(список_параметров) { Блок инструкций, выключающий инструкцию return значение: } Находит произведение двух чисел: #unclude <iostream.h> #include <windows.h> double MyFunction (int a, double b) { double c; c=a*b; return c; }
int main() { int SomeVar=4; double SomeVar2=0.5; SetConsoleOutputCP (1251); cout <<"Результат работы функции: " << MyFunction(SomeVar, SomeVar2) << endl; system ("pause"); return 0;}
16. Массивы. Массив - это последовательная группа ячеек памяти, имеющих одинаковое имя и одинаковый тип, чтобы сослаться на отдельную ячейку необходимо указать имя массива и номер позиции элемента. Одномерные массивы: int A[10]; float B[100]; int C[3] = {32,27,64}. Если начальных значений меньше чем элементов в массиве, то оставшиеся элементы автоматически получают 0. Чтобы поменять местами надо : t=A[5];==> A[5]=A[10];==> A[10]=t; Многомерные массивы. Компилятор с++ поддерживает до 12-мерных массивов.
Каждый элемент в массиве а определяется именем элемента в форме a[i][j];a - это имя массива, a i и j - индексы , которые однозначно определяют каждый элемент в a. Пример: #include <iostream> void main() { double a[20][2]; for (int i=0;i<20; i++) for (int j=0;j<2; j++) { a[i][j]=i*j; cout <<a[i][j]<<' '; } cin.get(); return 0; }
17. Строки. Cтрока - это последовательность символов обрабатываемые как единый модуль. Строка в языке с++ - это массив символов оканчивающейся нулевым символом('\0') Строка доступна через указатель на первый символ в строки. Значением строки является адрес ее первого символа. Строка может быть объявлена либо как массив символов, либо как переменная типа указатель на char. Строку можно присвоить символьному массиву word[20] следующим оператором: cin >> word; так же ввод можно осуществить cin.getline , которая требует 3 аргумента: (массив символов, длина строки, символ ограничитель)
char Arrayl[80]; cin.getline (Arrayl, 80,'\n'); 1. char *strcpy*char *s1,const char *s2); Копирует строку s2 в массив символов s1. Возвращает значение s1.
2. char *strcpy(char *s1, const char *s2, size_t n); копирует не более n символов из строки s2 в массив символов s1. Возвращает значение s1.
3.char *strcat(char *s1, const char *s2);
Добавляет строку s2 к строке s1. Первый символ строки s2 записывается поверх завершающего нулевого символа строки s1. Возвращает значение s1.
4. char *strncat*char *s1, const char *s2, size_t n);
Добавляет не более n символов строки s2 в строку s1. Первый символ из s2 записывается поверх завершающего нулевого символа в s1. Возвращает значение s1.
5. int strcmp(const char *s1, const char *s2);
Сравнивает строки s1 и s2. Функция возвращает значение 0, меньшее, чем 0 или большее, чем 0, если s1 соответственно равна, меньше или больше, чем s2.
6. int strncmp (const char *s1, const char *s2, size_t n);
Cравнивает до n символов строки s1 со строкой s2. Функция возвращает значение 0, меньшее, чем 0 иди большее, чем n, если s1 соответственно равна, меньше или больше, чем s2.
7. size_t strlen (const char *s);
Определяет длину строки s. Возвращает кол-во символов, предшествующих завершающему нулевому символу. В заголовочном файле <stdlib.h> содержатся полезные функции преобразования строк в числа: double atof(const char* p); преобразует переданную строку в double;;
int atoi (const char* p); преобразует переданную строку в int; long atol (const char* p ); преобразует переданную строку в long.
18. Структуры. TYPEDEF и перечислимые типы. Структура - это составные типы данных, построенные с использованием других типов. Для описания элементов типа struct: Time timeObject, timeArray[10], *timePtr; добвляет timeObject переменной типа Time, timeArray - массивом с 10 элементами типа Time, а timePtr - указателем на объект типа Time.
Для доступа к элементам структура, используется операция точка и операция стрелка. Операция точка обращается к элементу структуры по имени переменной объекта или по ссылке на объект. cout <<timeObject.hour; Операция стрелка обеспечивает доступ к элементу структуры через указатель на объект. cout<<timePtr->hour; или (*timePtr).hour; Синонимы для определенных ранее типов данных, создаются с помощью ключего слова typedef тип новое_имя_типа;
Например: typedef float balance; Далее можно создать вещественную переменную, используя balance: balance past;
Задание типом с длинными описаниями более коротких имен используется для облегчения переносимости программ. Если машиннозависимые типы объявить с помощью оператора typedef, при переносе программы, потребуется внести изменения только в эти операторы. Перечисления (enum). enum им_типа {имя_константы [=значение],...};
Ключевое слово enum позволяет описать перечисляемый тип , представляющий переменные, которые могут принимать значение из заданного набора целых и именованных констант. Значение указанное в квадратных скобках по умолчанию равно 0, для первого из перечислений. Для любой другой константы, значений которой не указано, оно принимается равным предыдущему значения +1. enum Status { Success =1, Wait,Proceed,Error = -1 };
enum Err{ERR_READ,ERR_WRITE,ERR_CONVERT}; Err error; switch (error) { case ERR_READ: /* операторы */ break; case ERR_WRITE: /* операторы*/ break; case ERR_CONVERT: /*операторы*/ break; }
19. Способы упорядочивания информации. Сортировка методом прямого выбора. Под сортировкой массива подразумевается процесс перестановки элементов массива целью которого является размещение элементов в определенным порядке. a[1]<=a[2]<=..<=a[SIZE Сортировка включением; Обменная сортировка; Сортировка выбором; Сортировка разделением (Quicksort); Сортировка с помощью дерева (Heapsort); Сортировка со слиянием; Сравнение методов внутренней сортировки. Алгоритм сортировки методом прямого выбора:
1) просматривая массив от первого элемента, нужно найти минимальный элемент и поместить его на место первого, а первый на место минимального 2) просматривая массив со второго элемента нужно найти минимальный, в оставшейся части, и поместить его на место второго, а второй на место минимального 3) и так далее, до пред последнего элемента #include <iostream.h> #include <windows.h> #include<iomanip.h> void main() { const int ArraySize=10; int a[ArraySize]={2,6,4,8,10,77,1,100,-1,0}; int i,min,j,buf,k; for (i=0; i<ArraySize-1; i++) { min=i; for (j=i+1; j<ArraySize; j++) if (a[j]<a[min]) min=j; buf=a[i]; a[i]=a[min]; a[ming]=buf; for (k=0; k<ArraySize; k++) cout <<setw(4) <<a[k]; cout <<endl; } cin.get(); return; }
SIZE-1+SIZE-2+...+1=(SIZE^2-SIZE)/2
20. Способы упорядочивания информации. Сортировка методом прямого обмена. Под сортировкой массива подразумевается процесс перестановки элементов массива целью которого является размещение элементов в определенным порядке. a[1]<=a[2]<=..<=a[SIZE Сортировка включением; Обменная сортировка; Сортировка выбором; Сортировка разделением (Quicksort); Сортировка с помощью дерева (Heapsort); Сортировка со слиянием; Сравнение методов внутренней сортировки.
Сортировка методом прямого обмена: В основе алгоритма лежит обмен соседних элементов массив. Каждый элемент начиная с первого сравнивается с последующим и, если он больше следующего, то элементы меняются местами. Таким образом элементы с меньшем значением подвигаются к началу массива (всплывают), а элементы с большем значением продвигаются к концу массива (тонут). Поэтому этот метод называют методом пузырька.
int i,buf,k; for ( i=1; i<ArraySize-1; i++) { for (k=0; k<ArraySize-1; k++ ) if (a[k]>a[k+1]) { buf=a[k]; a[k]=a[k+1]; a[k+1]=buf; }
(SIZE^2-SIZE)/2
21. Способы упорядочивания информации. Сортировка методом вставки. Под сортировкой массива подразумевается процесс перестановки элементов массива целью которого является размещение элементов в определенным порядке. a[1]<=a[2]<=..<=a[SIZE Сортировка включением; Обменная сортировка; Сортировка выбором; Сортировка разделением (Quicksort); Сортировка с помощью дерева (Heapsort); Сортировка со слиянием; Сравнение методов внутренней сортировки. Сортировки методом вставки:
В начале обрабатывается массив со второго элемента, потом с третьего, с четвертого и т.д. В процессе обработки все предыдущие элементы, начиная с первого, сравниваются с элементом с которого началась обработка. Если окажется, что текущий элемент больше чем элемент с которого началась обработка, то все элементы начиная с текущего сдвигаются на один элемент вправо (на место элемента с которого начиналась обработка), а последний перемещается на освободившееся место. Сортировка вставками требует также порядка SIZE^2 операций сравнения и столько же перестановок элементов в массиве. #include <iostream.h>
#include <windows.h>
#include <math.h>
int main (void){
SetConsoleOutputCP(1251);
int A[10];
int N, j, x,s=0;
cout<<"Введите размер массива N="; cin>>N;
if (N>=1) { for (int i=0; i<N; i++){ cout<<"A["<<i<<"]="; cin>>A[i]; } //Сортировка метдом вставки: for (int i=1; i<N; i++){ x=A[i];
for(j=i-1; j>=0 && A[j]>x; j--)
A[j+1]=A[j]; // сдвигаем элементы вправо, пока не дошли
A[j+1]=x;} // место найдено - вставить элемент for (int i=0; i<N; i++) {cout<<"\nA["<<s<<"]="<<A[i]<<" "; s=s+1; } } else cout<<"N<0"<<endl;
system ("pause"); return 0; }
22. Поиск в массивах. Метод бинарного поиска. При решение многих задач, возникает необходимость определить, содержит ли массив, определенную информацию элемент. Задач такого типа называют поиском в массиве.
#include <iostream.h>
#include <windows.h>
int main()
{ SetConsoleOutputCP (1251);
int A[1000],k,j;
double a,p,N,x,s=0;
cout << "Введите размер массива: ";
cin >>N;
if (N>=1){ {
for (int i=0; i<N; i++){
cout<<"A["<<i<<"]=";
cin>>A[i]; }
}
for (int i=1; i<N; ++i){
x=A[i];
for(j=i-1; j>=0 && A[j]>x; --j)
A[j+1]=A[j];
A[j+1]=x;}
cout <<"\nЭлементы одномерного массива по возрастанию:";
for (int i=0; i<N; ++i){cout<<"\nA["<<s<<"]="<<A[i]<<" "; s=s+1; }
cout << "\n\nВведите число: ";
cin >> a;
int l = -1; // Нижняя граница
int u = N; // Верхняя граница
while (u>=l) {
k = (l + u) / 2;
if (A[k] == a) {cout<<"\nИндекс данного числа: "<<k<<endl; break; }
if (A[k] < a) l = k;
if (A[k] > a) u = k+1;
}} else cout <<"N<0"<<'\n'; system ("pause"); return 0; }
23. Динамические объекты. Динамическая память - это свободная память в которой можно во время выполнения программы выделять место в соответствие с потребностями. Доступ к выделенным участкам динамической памяти называемым динамическими переменными осуществляется только с помощью указателей. Время жизни динамической переменной от точки создания до явного освобождения памяти или до конца программы. В языке с++ используется 2 способа работы с динамической памятью. 1-способ используют семейство функций malloc и достался в наследство от С, 2-способ используют операции new и delete. Для выделения памяти в области динамического распределения используется ключевое слово new. После new необходимо указать тип объекта который будет размещаться в памяти. Это необходимо для определения размера области памяти, требуемой для хранения объекта. Например, написав new unsigned short int - мы выделим 2 байта памяти.
*void malloc(size_t size) - выделяет область памяти для размещения динамической переменной размером size байт. Для определения размера памяти, занимаемой переменными, может быть использован оператор sizeof. Тип size_t определен в stdlib.h и является беззнаковым целым типом, способным хранить размер памяти, выделяяемом при одном выхове malloc().
*void calloc (size_t, size_t size) - выделяет область памяти для размещения массива из n элементов по size байтов каждый.
void * realloc (void * pointer, size_t size) - изменяет размер области памяти, выделенной для хранения динамической переменной, расположенной по адресу pointer (при этом переменная может быть перенесена по другому адресу ).
void free (void * pointer) - освобождает область памяти по адресу pointer, выделенную ранее вызовами malloc, calloc или realloc. Пример1. Выделение памяти под динамический массив.
cin>>n; int *mas=new int[n]; //выделение памяти под массив delete mas; // освобождение памяти
Пример2. Выделение памяти под двумерные массивы.
int n,k,i, **mas; cin>>n; cin>>k; mas=new int*[n]; //выделение памяти под n указателей на строку for(i=0; i<n;i++) mas[i]=new int[k]; // выделение памяти для каждой строки по числу столбцов k for (i=0;i<n,i++) delete mas[i]; //освобождение памяти delete [] mas;
24. Списки. Добавление в конец списка. Удаление элемента. Линейные списки : самый простой способ связать множество элементов - это добавление к каждому элементу ссылке. так список наз. односвязным (однонаправленным). Если добавить в каждый элемент ссылку на предыдущий, то получится двусвязный список, если последний элемент в списке связать с первым, то получится кольцевой список. Над списками можно выполнять, следующие операции: 1) начальное формирования списка; 2) добавление элемента в конец списка; 3) чтение элемента с заданным ключом; 4) вставка элемента в заданное место списка; 5) удаление элемента с заданным ключом; 6) упорядочивание списка. struct Node{int d; Node *next; Node *prev;}; // Добавления в конец списка void add (Node **pend, int d) { Node *pv = ned Node; pv->d=d; pv->next =0; pv->prev = *pend; (*pend)->next=pv; *pend = pv; }
Node * find (Node* const pbeg, int d) { Node *pv = pbeg; while (pv) { if (pv->d ==d) break; pv = pv-> next; } return pv;} // Удаление элемента
bool remove (Node **pbeg, Node **pend, int key) { if (Node *pkey = find( *pbeg, key)) { //1 if (pkey ==*pbeg) { //2 *pbeg=(*pbeg)-> next; (*pbeg)->prev=0;} else if (pkey == *pend) { //3 *pend = (*pend)->prev; (*pend)->next=0;} else { //4 (pkey->prev)->next = pkey->next; (pkey->next)->prev =pkey->prev;} delete pkey; return true;} //5 return false;} //6
25. Списки. Формирование первого элемента списка. Поиск элемента по ключу. Линейные списки : самый простой способ связать множество элементов - это добавление к каждому элементу ссылке. так список наз. односвязным (однонаправленным). Если добавить в каждый элемент ссылку на предыдущий, то получится двусвязный список, если последний элемент в списке связать с первым, то получится кольцевой список. Над списками можно выполнять, следующие операции: 1) начальное формирования списка; 2) добавление элемента в конец списка; 3) чтение элемента с заданным ключом; 4) вставка элемента в заданное место списка; 5) удаление элемента с заданным ключом; 6) упорядочивание списка. Начальное формирование списка: struct Node{int d; Node *next; Node *prev;}; #include <iostream> // поиск элемента по ключу
using namespace std;
bool key (int i) { return (i==5); } // тут задаешь ключ
int main () { int myints[] = {1,2,3,4,5,6,7,8,9}; // 1 2 3 4 5 6 7 8 9
// границы диапазона:
int* pbegin = myints; // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^
pend = remove_if (pbegin, pend, key); // 2 4 6 8 5 6 7 8 9
cout << " диапазон содержит:";
for (int* p=pbegin; p!=pend; ++p)
cout << " " << *p;
cout << endl; return 0;} #include <iostream.h> // формирование первого элемента списка struct Node{ Node *next; Node *prev; }; Node * first (ind d); void add (Node **pend, int d); Node *find (Node * const pbeg, int i); bool (remove (Node **pbeg, Node **pend, int key); Node * insert ( Node * const pbeg, Node **pend, int key, int d); int main () Node *pbeg = first(1); // Формирование первого элемента списка
26. Списки. Формирование первого элемента списка. Вставка элемента. Линейные списки : самый простой способ связать множество элементов - это добавление к каждому элементу ссылке. так список наз. односвязным (однонаправленным). Если добавить в каждый элемент ссылку на предыдущий, то получится двусвязный список, если последний элемент в списке связать с первым, то получится кольцевой список. Над списками можно выполнять, следующие операции: 1) начальное формирования списка; 2) добавление элемента в конец списка; 3) чтение элемента с заданным ключом; 4) вставка элемента в заданное место списка; 5) удаление элемента с заданным ключом; 6) упорядочивание списка. Начальное формирование списка: struct Node{int d; Node *next; Node *prev;}; Node * insert ( Node* const pbeg, Node **pend, int key, int d) { //вставка элемента if (Node *pkey = find (pbeg, key)) { Node *pv=new Node; pv->d=d; // 1 - установление связи нового узла нового узла с последующим : pv->next=pkey->next; //2 - установление связи нового узла с предыдущим: pv->prev = pkey; //3 - установление предыдущего узла с новым : pkey -> next = pv; // 4 - установление связи последующего узла с новым : if (pkey!= *pned) (pv->next)->prev = pv; // обновление указателя на конец списка , если узел вставляется в конец : else *pend = pv; return pv;} return 0; }
#include <iostream.h> // формирование первого элемента списка struct Node{ Node *next; Node *prev; }; Node * first (ind d); void add (Node **pend, int d); Node *find (Node * const pbeg, int i); bool (remove (Node **pbeg, Node **pend, int key); Node * insert ( Node * const pbeg, Node **pend, int key, int d); int main () Node *pbeg = first(1); // Формирование первого элемента списка
27. Стеки. Начальное формирование стека. Занесение в стек. Стек – это линейный список, в котором добавление новых элементов и удаление существующих производится только с одного конца, называемого вершиной стека. Стек – это такой список, добавление или извлечение элементов которого происходит с начала и только с начала (или, возможно, с конца и только с конца) списка. Добавление элементов в стеки и выборка осуществляется с одного конца, называемого вершиной стека. Другие операции со стеком не определены.
#include <iostream.h> struct Node { int d; Node *p; }; Node * first (int d ); void push (Node **top, int d); int pop (Node **top);
// Начальное формирование стека
Node * first (int d) { Node *pv=new Node; pv->d=d; pv0->d=0; return pv; }
// Занесение в стек
void push (Node **top, int d){ Node *pv = new Node; pv->d=d; pv->p=*top; *top=pv;}
28. Стеки. Начальное формирование стека. Выборка из стека. Стек – это линейный список, в котором добавление новых элементов и удаление существующих производится только с одного конца, называемого вершиной стека. Стек – это такой список, добавление или извлечение элементов которого происходит с начала и только с начала (или, возможно, с конца и только с конца) списка. Добавление элементов в стеки и выборка осуществляется с одного конца, называемого вершиной стека. Другие операции со стеком не определены.
#include <iostream.h> struct Node { int d; Node *p; }; Node * first (int d ); void push (Node **top, int d); int pop (Node **top);
// Начальное формирование стека
Node * first (int d) { Node *pv=new Node; pv->d=d; pv0->d=0; return pv; } // Выборка из стека int pop (Node **top){ int temp = (*top) ->d; Node *pv = *top; *top =(*top)->p; delete pv; return temp; }
29. Очереди. Начальное формирование очереди. Добавление элемента. Выборка. Это частный случай списка, добавление в который выполняется в один конец , и выборка из другого конца. Другие операции с очередью не определены. При выборки элемент исключается из очереди. В очереди реализован принцип: первым пришел - первым ушел. #include <iostream.h> struct Node { int d; Node *p;}; Node *first
int main (){ Node *pbeg = first (1); Node *pend=pbeg; for *int i=2; i<6; i++) add (&pend,i); while (pbeg) cout <<del (&pbeg)<<' '; cin.get (); return 0;}
// начальное формирование очереди
Node * first (int d) { Node *pv = new Node; pv->d = d; pv->p = 0; return pv;}
// добавление в конец
void add(Node **pendm int d){ Node *pv = new Node; pv->d=d; pv->p=0; (*pend)->p=pv; *pend = pv;}
// Выборка int del(Node **pbeg) { int temp = ( *pbeg)->d; Node *pv=*pbeg; *pbeg = (*pbeg)->p; delete pv ; return temp }
30. Многофайловые проекты. Тестирование и отладка. Исходные текст, совокупности функции для решения какой-либо задачи, размещаются в отдельном модуле(файле). Такой файл называется исходным и имеет расширении .c или .cpp . Прототипы всех функций исходного файла вносят в отдельный так называемый заголовочный файл. Для него принято использовать расширение .h или .hpp . таким образом заголовочный файл xxx.h содержит интерфейс для некоторого набора функций, а исходный файл xxx.cpp содержит реализацию этого набора. Если некоторая функция из указанного набора, вызывается их какого-то другого модуля, то необходимо включить в этот модуль заголовочный файл xxx.h с помощью директивы include. Разбиение на модули - уменьшает время перекомпиляции и облегчает процесс откладки. Скрывая детали реализации за интерфейсом. Называются заголовки всех функция описания всех типов переменных и констант. #include "Unit2.h"; #include "Unit2.cpp"; 1.Пошаговый режим - представляет собой процесс исполнения программы при котором за один раз, исполняется одна инструкция. Для реализации этого режима необходимо нажать F7. Если нажмем F8, то отладчик не будет заходить в функции.
Точки останова breakpoint
В больших программах используемый может быть очень утомительно, поэтому вместо нажатия F7 или F8 для достижения отлагаемого участка кода, использовать точки останова в начале критического участка кода. Когда выполнение программы достигает точки останова, программа прекращает исполняться до того. Затем управление возвращается отладчику, что позволяет проверить значение определенных переменных или начать режим "пошаговой отладки". Имеются 2а основных типа: условные и безусловный. Безусловные точки останова всегда прекращают исполнение как только они встретится в программе. Чтобы добавить точку останова необходимо установить курсор на нужной строке кода и нажать F5 или двойной щелчок мыши .
Установка условных точек останова
Условные точки останова позволяют указать условие при которых эти точки прекратят выполнение программы, а так же определить действие, которые при этом произойдут.
Run-> Add Breakpoint Кнопка Advanced. Для этого можно воспользоваться Pass Count и установить поле Up to равным числу итераций, которое надо выполнить.
Просмотр переменных Add Watch. Для этого нажимаем CTRL-F5
Вычисление выражений Evaluate/Modify. Активизировать это окно можно нажав клавиши CTRL-F7.
31. Директивы препроцессора. Пространство имен. Директива #include - применяется для включения указанного файла в то место где находится эта директива. Существует 2 формы записи: #include <имя_файла>; #include "имя файла" Различие между этими формами записи заключается в методе поиска предпроцессора, включаемого файла. Если имя заключено в угловые скобки, то последовательность поиска предпроцессора, заданного файла каталога определяется в заранее установленного в списке. Если имя файла заключено в кавычки, предпроцессор с начало ищет файл в том каталоге где находится компилированный файл, а затем продолжает поиск тем же способом, что и при угловых скобках. Такой формой обычно пользуются для включение заголовочных файлов, определяемых программистом. Директива #define - директива предпроцессора создает символические константы, обозначаемые идентификатором и макросы. Операции обозначаемые символьными строками. #define идентификатор заменяющий_текст #define PI 3.14159. После появление этой строки в файле, все встретившие далее в тексте программы имена, совпавшие переменной директивы идентификатор будут автоматически заменены директиве, замещающей текст, до начало компиляции программы. Пространство имен. Конфликт имен возникает в тех случаях, когда в 2ух частях программы находятся одинаковые имена с совпадающими областями видимости. Под областью видимости объекта понимают ту часть программы в которой данный объект может использоваться. Глобальное пространство имен может быть разбита на несколько пространств. namespace имя { // объявление объекта } Кроме того, можно использовать безымянное пространство имен, как показано ниже: namespace { // объявление объекта }
namespace MyNameSpace { int i,k; void myfune (int j) {cout << j ;} } MyNameSpace::i = 10;
using namespace имя; using имя:: член пространства имен;
using MyNameSpace::k; // видим только k k=10; // допустимо, поскольку k видим using namespace MyNameSpace; // все члены MyNameSpace видимы i=10; // допустимо, поскольку все члены MyNameSpace видимы