1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
//Листинг #1 #include <iostream> using namespace std; /*НАША СТРУКТУРА*/ struct List { int x; //информационный элемент List *Next,*Head; //Голова стека и указатель на следующий элемент }; /*ФУНКЦИЯ ДОБАВЛЕНИЯ ЭЛЕМЕНТА В СТЕК (в список LIFO)*/ void Add(int x, List *&MyList) //Принимаем элемент стека и указатель на стек, при этом говорим, что принимаемый указатель будет сам по себе указателем { List *temp = new List; //Выделяем память для нового элемента temp->x = x; //Записываем в поле x принимаемый в функцию элемент x temp->Next = MyList->Head; //Указываем, что следующий элемент это предыдущий MyList->Head = temp; //Сдвигаем голову на позицию вперед } /*ФУНКЦИЯ ОТОБРАЖЕНИЯ СТЕКА*/ void Show(List *MyList) //Нужен только сам стек { List *temp = MyList->Head; //Объявляем указатель и Указываем ему, что его позиция в голове стека //с помощью цикла проходим по всему стеку while (temp != NULL) //выходим при встрече с пустым полем { cout << temp->x << " "; //Выводим на экран элемент стека temp = temp->Next; //Переходим к следующему элементу } } /*ФУНКЦИЯ УДАЛЕНИЯ СТЕКА ИЗ ПАМЯТИ*/ void ClearList(List *MyList) { while (MyList->Head != NULL) //Пока по адресу не пусто { List *temp = MyList->Head->Next; //Временная переменная для хранения адреса следующего элемента delete MyList->Head; //Освобождаем адрес обозначающий начало MyList->Head = temp; //Меняем адрес на следующий } } int main() { List *MyList = new List; //Выделяем память для стека MyList->Head = NULL; //Во избежание ошибок инициализируем первый элемент for (int i=0; i<10; i++) Add(i,MyList); //Заносим данные в стек Show(MyList); //Выводим стек на экран ClearList(MyList); //Очищаем память. delete MyList->Head; delete MyList; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
//Листинг #2 Стек LIFO #include <iostream> struct stek { int value; struct stek *next; // указатель на следующий элемент списка (стека) }; void push(stek* &NEXT, const int VALUE) { stek *MyStack = new stek; // объявляем новую динамическую переменную типа stek MyStack->value = VALUE; // записываем значение, которое помещается в стек MyStack->next = NEXT; // связываем новый элемент стека с предыдущим NEXT = MyStack; // новый элемент стека становится его вершиной } int pop(stek* &NEXT) { int temp = NEXT->value; // извлекаем в переменную temp значение в вершине стека stek *MyStack = NEXT; // запоминаем указатель на вершину стека, чтобы затем // освободить выделенную под него память NEXT = NEXT->next; // вершиной становится предшествующий top элемент delete MyStack; // освобождаем память, тем самым удалили вершину std::cout << temp; //Вывод текущего элемента на экран return temp; // возвращаем значение, которое было в вершине } int main() { stek *p=0; push(p,100); //Положили в стек 100 push(p,200); //Положили в стек 200 pop(p); //вывели на экран текущий элемент стека = 200 pop(p); //вывели на экран текущий элемент стека = 100 return 0; } |
Малочик!
Спасибо!!!
Спасибо, большое.
СПАСИБО огромное!
благодаря тебе мы сдадим лабу!!! :****
😳 🙂 👿 😛 ❓ 😛 🙁
LIFO (Last In, First Out) — последний пришел, первый ушел. Смотрите абзац: Часто стек сравнивают с ящиком…
спасибо огромное!!!!!
пасиба памагли
Это самый лучший стек который я видел, огромный респект автору,кратко,четко, по существу, очень помог, спасибо!
ОГРОМНОЕ СПАСИБО АВТОРУ!!! ВСЕ ЗДОРОВО ВСЕ ПОНЯТНО теперь получу допуск к экзамену)
только вот компилятор ругался на эти строки
я заменил так и все заработало)
Здрааасьте)
Спасибо
Только что попробовал запустить программу, компилятор выдал ошибку, что Х не объявлен в функции добавления. Я исправил немного код, необходимо было еще добавить (temp->x). Я просто подумал может кому-то понадобиться.
Автор, в первом примере стека у Вас утечка памяти. Внимательно проверьте код еще раз. Как вообще можно было такое написать? Последний элемент всегда занимает память и не освобождается. К краху это не приводит, но память съедается.
Да, есть утечка, исправлю. Чем кроме этого вас такое написание не устраивает?
К первому больше нечего придираться. А вот ко второму… В функции pop в аргументе Вы передаете указатель на ссылку. По Вашим утверждением в комментариях, мол не будет создаваться копия, на самом деле все равно будет, но копия переданной переменной-указателя, то есть копия адреса все равно создается. К слову можно юбыло обойтись просто указателем. Все вроде.
Почему она должна создаваться и чем это отличается от создаётся локальная копия адреса внутри функции, мне кажется тут вы заблуждаетесь. Происходит обычная передача указателя по ссылке.
Может быть заблуждаюсь, однако по Стивену Прата и Страуструпу:
Там говорится о том, что сама переменная-аргумент, даже в таком виде:
void func (int *arg);
Так вот адрес попеёод переменную arg также выделяется память для хранения копии адреса переданного ууеазателя.
т.е
int a = 5;
int *p_a = &a;
func (p_a);
В данном случае действительно данные из а не копируются, а вот значение переменной p_a, то есть адрес переменной а передается в новый указатель arg. Если бы этого не происходило, то Вы могли бы в функции func написать такое:
arg = какой-какой-то адрес;
И указатель p_a поменял бы свое значение и указывал бы на что-то другое и пятерка бы не вывелась. Этого не происходит так как в действительности мы все равно работаем с копией, только уже копией адреса. В общем проверьте пример, посиотрите что Стивен Прата пишет, Вы поймете.
Есть более простой пример доказать мне мою неправоту.
И все встает на свои места. Я ошибся. Надо не **, а *&
Спасибо, что указали на этот момент. Я считал, что ** то же, что и *&, а оно вон он какое хитрое оказывается.
Если на что еще наткнетесь, дайте знать. Спасибо за помощь.
Если обойтись просто указателем, то, вроде бы, должно действовать общее правило для всех локальных переменных. По завершению функции копия указателя уничтожается. Любое обращение к тому что там было — это как обращение к мусорным переменным, что может вызвать крах программы.
(Я могу ошибаться, но по моей логике так)
Для очистки стека кстати можно было бы просто while звзаменить на do — while и перед циклом проверку на непостоту текущего элемента вставить.
Я поправил немного не как вы просили. Проблема с утечкой решена?
Да, так решена.
Накатал свой вариант стека совместил несколько программ может кому-нибудь понадобится
помогите)) где нужно прописать этот код класса со стеком!? я его прописывала в
Microsoft Visual Studio, c расширением «.с» где найти как поэтапно создать эту программу с правильным расширением и настройками
В основном окне программы. Так же само как HelloWorld на экран вывести
Объясните, пожалст — в 1-й строчке:
каким образом работают эти строчки? указателю «Next» становится равен указатель » Head». Почему на «Next» указывает указатель «temp», а на » Head » указатель «MyList»?
во 2-й строчке:
указателю «Head» на который указывает » MyList » приравнивается значение указателя » temp» ?
А чему тогда равно значение указателя ” temp” ?
temp Просто указывает на область памяти, которая хранит блок стека. Для удобства можно воспринимать этот temp блоком памяти, хотя он блоком памяти не является. А из этого блока памяти нам доступны отдельные кусочки этого блока, эти кусочки нам и нужны. Их я в примере и задействываю. temp — это указатель на начало такого блока памяти.
Есть предложение заменить во втором примере аргументы d и next на другие переменные, а то так запутаться можно.
спасибо!
Если нужно сначала ввести число в стек (диалог с пользователем), после ввода числа вывести массив из чисел.
К примеру ввели число с клавиатуры 1, после это он вывел само число 1 и остальные числа. Как реализовать с помощью ввода, чтобы сначала число вводить потом вывод всех чисел на экран?
а почему тут копия указателя, а не *& для изменений
/*ФУНКЦИЯ УДАЛЕНИЯ СТЕКА ИЗ ПАМЯТИ*/
void ClearList(List *MyList)
Я так делал, чтобы не повредить внешний для функции указатель. Ни к чему его изменять, незачем его смещать.
Почистить память можно и внутренним обходительством.
😳
До чего уродливое оформление! Автору кол в сердце!