Использование функций STL stack::top и stack::empty в Visual C++
В этой статье показано, как использовать stack::top функции STL и stack::empty в Visual C++. Сведения, приведенные в этой статье, относятся только к неуправляемого кода Visual C++.
Исходная версия продукта: Visual C++
Оригинальный номер базы знаний: 158040
Обязательный заголовок
Прототип
template // Function 1 value_type &stack::top(); template // Function 2 const value_type &stack::top() const; template // Function 3 bool stack::empty() const;
Имена классов или параметров в прототипе могут не соответствовать версии в файле заголовка. Некоторые из них были изменены для повышения удобочитаемости.
Описание функций stack::top и stack::empty
Функция top возвращает самый верхний элемент стека. Перед вызовом top функции убедитесь, что в стеке есть один или несколько элементов. Первая версия top функции возвращает ссылку на элемент в верхней части стека, что позволяет изменить значение. Вторая функция возвращает константную ссылку, гарантируя, что вы случайно не измените стек.
Функция empty возвращает значение true , если в стеке нет элементов. При наличии одного или нескольких элементов функция вернет значение false. Функцию следует использовать, empty чтобы убедиться, что в стеке остались элементы, прежде чем вызывать функцию top .
Пример кода
////////////////////////////////////////////////////////////////////// // Compile options needed: /GX // StackTop&Empty.cpp : Illustrates how to use the top function to // retrieve the last element of the controlled // sequence. It also illustrates how to use the // empty function to loop though the stack. // Functions: // top : returns the top element of the stack. // empty : returns true if the stack has 0 elements. // Copyright (c) 1996 Microsoft Corporation. All rights reserved. ////////////////////////////////////////////////////////////////////// #pragma warning(disable : 4786) #include #include #if _MSC_VER > 1020 // if VC++ version is > 4.2 using namespace std; // std c++ libs implemented in std #endif typedef stack> STACK_INT; void main() < STACK_INT stack1; cout // Repeat until stack is empty while (!stack1.empty()) // Function 3 < const int &t = stack1.top(); // Function 2 cout >
Обратная связь
Были ли сведения на этой странице полезными?
Как передать стек в функцию с
На этом шаге мы рассмотрим общий алгоритм передачи параметров через стек .
Здесь нам хотелось бы рассмотреть подробнее вопрос о передаче параметров через стек. Мы уже останавливались на нем (шаг 36 в разделе «Assembler: 16-битное программирование»). Это не единственный способ передачи параметров, но именно через стек передаются параметры API -функциям, поэтому на это необходимо обратить внимание. Состояние стека до и после вызова процедуры приводится на рисунке 1.
Рисунок 1 демонстрирует стандартный вход в процедуру, практикующийся в таких языках высокого уровня, как Паскаль и Си.
Рис.1. Схема передачи параметров в процедуру (стек растет сверху вниз)
При входе в процедуру выполняется стандартная последовательность команд:
PUSH EBP MOV EBP, ESP SUB ESP, N; N - количество байт для локальных переменных.
Адрес первого параметра определяется как [ЕВР+08Н] , что мы уже неоднократно использовали. Адрес первой локальной переменной, если она зарезервирована, определяется как [ЕВР — 4] (имеется в виду переменная типа DWORD ). В конце процедуры идут команды:
MOV ESP, ЕВР POP EBP RET M
Здесь M — объем, взятый у стека для передачи параметров.
Такого же результата можно добиться, используя команду
ENTER N, 0
(заменяет последовательность команд:
PUSH EBP MOV EBP, ESP SUB ESP
) в начале процедуры и
LEAVE
(заменяет последовательность команд:
MOV ESP, ЕВР РОР ЕВР
в конце процедуры. Эти команды появились еще у 286-го процессора и дали возможность несколько оптимизировать транслируемый код программы, особенно в тех случаях, когда речь идет о больших по объему модулях, создаваемых на языке высокого уровня.
Хотелось бы остановиться еще на одном вопросе, связанном со структурой процедуры и ее вызова. Существуют два основных подхода к передаче параметров , или, как еще говорят, соглашения о передаче параметров . Условно первый подход можно назвать Си-подходом, а второй — Паскаль-подходом . Первый подход предполагает, что процедура «не знает», сколько параметров находится в стеке. Естественно, в этом случае освобождение стека от параметров должно происходить после команды вызова процедуры , например, с помощью команды POP или команды ADD ESP,N ( N — количество байт, занятых параметрами). Второй подход основан на том, что количество параметров фиксировано, поэтому стек можно освободить в самой процедуре . Это достигается за счет выполнения команды RET N ( N — количество байт в параметрах). Как вы уже, наверное, догадались, вызов функций API осуществляется, чаще всего, по второй схеме.
Со следующего шага мы перечислим общие принципы построения оконных приложений .
Как передать стек в функцию с
Указатель на функцию фактически представляет некоторый тип, и функция также может иметь параметр, который представляет тип указателя на функцию. Таким образом, мы можем через параметр на функцию передавать в одну функцию другую. То есть функция может быть аргументом другой функции.
#include int add(int, int); int subtract(int, int); int operation(int(*)(int, int), int, int); // первый параметр — указатель на функцию int main() < int a; int b; int result = operation(add, a, b); std::cout int add(int x, int y) < return x + y; >int subtract(int x, int y) < return x - y; >int operation(int(*op)(int, int), int a, int b)
В данном случае первый параметр функции operation — int (*op)(int, int) — представляет указатель на функцию, которая возвращает значение типа int и принимает два параметра типа int . Результатом функции является вызов той функции, на которую указывает указатель.
Определению указателя соответствуют две функции: add и subtract, поэтому их адрес можно передать в вызов функции operation: operation(add, a, b); .
Результат работы программы:
result: 16 result: 4
Функция, передаваемая другой функции в качестве аргумента, называется функцией обратного вызова или коллбек (callback). А функция, которая принимает другую функцию в качестве аргумента, является функцией высшего порядка. Таким образом, в примере выше функция operation представляет функцию высокого порядка, а функции add и subtract — функции обратного вызова.
Рассмотрим другой пример — определим функцию, которая может принимать в качестве параметра некоторое условие и вычислять все элементы массива, которые соответствуют этому условию:
#include // функции, которые представляют условия bool isEven(int); // если число четное bool isPositive(int); // если число положительное // Функция для определения элементов массива, которые соответствуют некоторому условию // функция принимает условие — bool(*)(int) // массив — int[] // размер массива — unsigned void action(bool(*)(int), int[], unsigned); int main() < int numbers[]< -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 >; const unsigned n < std::size(numbers)>; // находим длину массива std::cout bool isEven(int x) < return x % 2 == 0; >bool isPositive(int x) < return x >0; > void action(bool(*condition)(int), int numbers[], unsigned n) < // перебираем массив for (unsigned i<>; i < n; i++) < // если число (numbers[i] соответствует условию condition if (condition(numbers[i])) < std::cout > std::cout
Функция action в качестве первого параметра принимает некоторую функцию, которая задает условие, которому должны соответствовать элементы массива. Это условие представляет указатель bool (*condition)(int) . То есть это некоторая функцию, которая принимает целое число и в зависимости от того, соответствует оно условию или нет, возвращает значение типа bool ( true , если число из массива соответствует условию, и false , если не соответствует). На момент определения функции action точное условие может быть неизвестно.
В текущей программе условия представлены двумя функциями. Функция isEven() возвращает true, если число четное, и false, если число нечетное. А функция isPositive() возвращает true, если число положительное, и false, если отрицательное.
Второй параметр функции action — массив чисел int, для которых вызываем условие. А третий параметр — размер массива. Если число соотвествует условию, то выводим это число на консоль
void action(bool(*condition)(int), int numbers[], unsigned n) < // перебираем массив for (unsigned i<>; i < n; i++) < // если число (numbers[i] соответствует условию condition if (condition(numbers[i]))
При вызове функции action() в нее можно передать нужное условие:
action(isEven, nums, n); action(isPositive, numbers, n);
В итоге программа выведет на экран числа из массива nums, которые соответствуют переданному условию:
Even numbers: -4 -2 0 2 4 Positive numbers: 1 2 3 4 5
Как передать объект «Стек» в функцию?

Интересует такой вопрос, а как передать класс стека в параметр процедуры или функции?
например программа, и хочу сделать чтобы она была через процедуру или функцию
то есть что вроде вот этого AddInStack(int value, stack string)
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#include "stdafx.h" #include #include #include "StackFuctions.h" using namespace std; //главная функция void main() { setlocale(LC_ALL, "Russian"); char number; int value; stack int> S; do { cout <"1. Добавить элемент"; cout <"2. Удалить элемент"; cout <"3. Получить верхний элемент"; cout <"4. Узнать размер стека"; cout <"5. Освободить стек"; cout <"6. Вывести содержимое стека,с последующей отчисткой"; cout <"0. Выйти"; cout <"Номер команды > "; cin >> number; switch (number) { case '1': //добавление элемента cout <"Значение > "; cin >> value; AddInStack(value, S); break; //----------------------------------------------- case '2': //удаление элемента if (S.empty() == true) cout <"\nСтек пуст\n\n"; else { S.pop(); cout<"Элемент удален из стека\n\n"; } break; //----------------------------------------------- case '3': //вывод верхнего элемента if (S.empty() == true) cout <"\nСтек пуст\n\n"; else cout <"\nВерхний элемент стека: " top () <"\n\n"; break; //----------------------------------------------- case '4': //вывод размера стека if (S.empty() == true) cout <"\nСтек пуст\n\n"; else cout <"\nРазмер стека: "size () <"\n\n"; break; //----------------------------------------------- case '5': // отчистка стека if (S.empty() == true) cout <"\nСтек пуст\n\n"; else cout <"\nСтек освобожден\n\n "; while (!S.empty()) S.pop(); break; //----------------------------------------------- case '6': // Вывод содержимого if (S.empty() == true) cout <"\nСтек пуст\n\n"; else cout <"\nЧисла: "; for (; S.size(); S.pop()) cout <" "top (); cout <"\nСтек освобожден\n\n "; break; //----------------------------------------------- case '0': break; //выход default: cout<"Команда не определена\n\n"; break; } } while (number != '0'); system("pause"); }