Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
1-50_1.docx
Скачиваний:
9
Добавлен:
02.08.2019
Размер:
707.62 Кб
Скачать
  1. Статические и динамические переменные, динамическая память, работа с динамическими переменными.

Переменная – это именованная область памяти, в которой хранятся данные определённого типа. У переменной есть имя и значение. Имя служит для обращения к области памяти, в которой хранится значение. Во время выполнения программы, значение переменой можно изменять. Перед использованием любая переменная должная быть описана. Например int i,j;

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

Каждая статистическая переменная описанная в некотором блоке и обращение к ней осуществляется с помощью ее имени – идентификатора. Обратиться к динамическим переменным можно с помощью указателя на место текущего расположения - куча /

int x=15 статическая переменная х, в статической памяти -4 байта и записано число 15.

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

х=new(int) –d динамической памяти место для хранения величины целого типа и и адрес этой области памяти присвоен указателю х.

х – имя указателя и его значение – адрес байта динамической памяти , начиная с с которого размещается динамическая переменная *х.

Создание:

  1. описание указателя <тип>*<идентификатор> (int *x)

и обратиться к стандартной функции new? которая выделяет в динамической области памяти область, достаточную для хранения и присваивает указателю адрес этой области:<указатель>=new(<тип>), х=new(int)

  1. int*x=new(int) или int *x=new int;

x=NULL – указатель ни на что не ссылается.

После использования динамической переменной ее нужно удалить: delete < имя указателя >

Примеры:

  1. int*x=new(int)*y // описаны 2 указателя и создана динамическая переменная Х

  2. *х=10; y=x // указателю У присваиваем значение указателя х, т.е имеем 2 указателя на область динамической памяти.

  3. *y=7 // изменили содержимое динамической памяти.

  4. y=NULL // присвоили пустую ссылку

  5. cout<<*x; //7

Пример:

int main() {

int *x=new(int), y=new(int); int r;

*x=10; *y=20;

cout<<*x<<”\t”<<*y<<endl;

r=*x; *x=*y; *y=r;

cout<<*x<<”\t”<<*y<,endl;

delete x; delete y;

return 0;}

Динамическая структура :

struct stud {

string fio;

int kurs;

stud*next;};

в структуре типа Stud введено поле, тип его определяется указателем определяемого типа stud*next, т.е значение этого поля –адрес следующего студента в списке.

  1. Понятие линейного связного списка, типы списков, представление стека с помощью массива, пример использования стека.

Линейный список-множество, состоящее из n>=0 компонент, структурные свойства которого ограничиваются линейным, одномерным относительным положением компонент: х[1]....x[n] Если n>0 то x[1] -1я компонента, x[n]-последняя.

Операции над списками:

  1. получить допуск к К-й компоненте списка (посмотреть/изменить содержимое ее полей)

  2. включить новую компоненту в список перед К-й компонентой

  3. исключить из списка К-ю компоненту

  4. объединить 2 и более списка в один

  5. разбить линейный список на 2 и более

  6. сделать копию линейного списка

  7. определить количество компонент в списке

  8. отсортировать компоненты списка по значению некоторых полей

  9. 9) найти в списке компоненту с заданным значением некоторого поля.

Линейный связанный список – конечное множество компонент, состоящих из 2х частей : информационной (info) и указательной (link)

Если link содержит 1 адрес, указывает какая компонента следует за данной, то это –однонаправленный, односвязный список.

Если же 2 адреса, то двунаправленный.

Линейные последовательности можно представить с помощью массива., т.к индекс – прямой доступ к любой компоненте. Пусть в массиве stk[i] фамилии; надо +1 и -2 фамилии, тогда связный список может быть реализован как двумерный массив. 1й столб – неупорядоченные фамилии (info), 2 й столб (link)-№ строки массива, содержащих фамилию следующего в списке студента в алфавитном порядке.

Стек – линейный список, в котором все включения и исключения (ввод/вывод данных) и всякий доступ к данным осуществляется с одной стороны. Принцип работы LIFO:

Описание стека: const int stacksize=100; int stack[stacksize],x,sp;

sp- специальная переменная (указатель стека) что бы обратиться к вершине если стек не пуст, то указатель стека sp указывает на 1й элемент массива.

sp=0 – инициализирует стек, делает его пустым.

  1. stack [sp]=x; ..положить х на вершину стека

sp=sp+1; ..указатель стека переместить на следующую компоненту.

  1. sp=sp-1; // указатель уменьшаем на 1;

x=stack[sp]; ..присваиваем значение последнего элемента в списке.

Другая реализация:

  • Положить в стек if (sp=stacksize) cout<<”стек полон”;

  • Взять из стека else { stack[sp]=x; sp=sp+1;}

if (sp<1) cout<<”стек пуст”;

else {sp =sp-1; x=stack[sp];}

  • Если sp указывает на первый занятый элемент в стеке, на его вершину, то:

sp=sp+1; stack[sp]=x;

x=stack[sp]; sp=sp-1;

Примеры использования.

-инфиксная х+y*z-a/(b+c)

-префиксная -+*xyz/+abс

- постфиксная xyz*+abc+/- (ОПЗ)

Пусть входная строка – выражение в инфиксной форме, а выходная в форме ОПЗ.

операторы из входной строки попадают в выходную, а знаки операций имеют приоритет:

( 0

) 1

+ - 2

*/ 3

Если очередной символ входной строки - знак операции, а его приоритет равен нулю или больше приоритета знака операции, находящегося на вершине стека, то этот знак из входной строки помещается в стек, в противном случае из стека в выходную строку вытесняются все знаки с приоритетом >= приоритету входного знака. После этого знак – на вершину.

Если символ во входной строке – правая скобка, то из стека вытаскиваются все знаки операций до 1й левой скобки , скобки взаимно уничтожаются.

xyz*+abc+/* + x+y*z-a/(b+c)

(

/

-

*

+

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]