Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.78/328: Рейтинг темы: голосов - 328, средняя оценка - 4.78
zss
Модератор
Эксперт С++
7482 / 6851 / 4324
Регистрация: 18.12.2011
Сообщений: 18,122
Завершенные тесты: 1
1

Образцы (шаблоны) программ для типовых задач

10.03.2015, 11:35. Просмотров 61556. Ответов 19
Метки нет (Все метки)

Постим сюда образцы программ для решения типовых задач.

Образцы не должны быть истиной в последней инстанции,
а только иллюстрацией (идеей) оформления решения.

Содержание
1. Образец для обработки матриц (двумерных динамических массивов)

2. Образец для одномерного массива (вектора)

3. Образец для создания классов (базовый, производный, виртуальная функция)

4. Базовый класс для любого конечного автомата.

5. Велосипедный стек на односвязном списке

6. Вычисление значения кусочно заданной функции

7a. Функция с переменным числом параметров
7b. Вычисление суммы чисел функцией с переменным числом аргументов при помощи variadic templates (c++11)
7с. Функция с переменным числом параметров использующая std::initializer_list
13
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.03.2015, 11:35
Ответы с готовыми решениями:

Комплекс типовых задач обработки числовых одномерных массивов
1. Разработать и отладить программу на С++ для решения комплекса типовых задач...

Программирование типовых числовых задач обработки одномерных массивов
1) Вычислить и запомнить в структуре одномерного массива (таблица 1)...

Алгоритм генерации типовых задач по теме "Многочлены"
Помогите с алгоритмом) никак не могу написать алгоритм генерации((( Например,...

Решение задач (создание программ) на С/С++ за плату
Господа, нужно помощь. Необходимо выполнить несколько лабораторных работ на...

Подскажите сайт, на котором куча задач по написанию программ
нужен сайт, на котором куча задач по написанию программ(на паскальке или c++......

19
zss
Модератор
Эксперт С++
7482 / 6851 / 4324
Регистрация: 18.12.2011
Сообщений: 18,122
Завершенные тесты: 1
10.03.2015, 11:36  [ТС] 2
Образец для обработки матриц (двумерных динамических массивов)
C++
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
//#include <clocale>
using namespace std;
//----- объявление прототипов используемых функций-----------------
int** Create(int n,int m);           // создание матрицы n строк m столбцов
void Free(int** M,int n);             // освобождение матрицы
void Input(int** M,int n,int m);   // ввод матрицы
void Print(int** M,int n,int m);     // вывод матрицы
//--------------------------------------------------------------------------
void Work(int** M,int n,int m);    // обработка матрицы
//   Сюда добавить протопипы тех функций которые дополнительно напишете
//--------------------------------------------------------------------------
 
//----------  main() -  точка входа в программу консольного приложения 
int main()
{
    //setlocale(LC_ALL,"Rus");
    int n,m;
    cout<<"Количество строк матрицы:?";
    cin>>n;
    cout<<"Количество столбцов матрицы:?";
    cin>>m;
    int** A=Create(n,m);
    Input(A,n,m);
    Work(A,n,m);
    Free(A,n);
    //system("pause");
    return 0;
}
 
//----   описание функций -----------------------------------------
int** Create(int n,int m)
{
    int** M=new int*[n];
    for(int i=0;i<n;i++)
    {
        M[i]=new int[m];
    }
    return M;
}
//----------------------------
void Free(int** M,int n)
{
    for(int i=0;i<n;i++)
        delete[] M[i];
    delete[] M;
}
//----------------------------
void Input(int** M,int n,int m)
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cout<<"M["<<i<<"]["<<j<<"]=?";
            cin >> M[i][j];
        }
    
    }
}
//----------------------------
void Print(int** M,int n,int m)
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cout << M[i][j] << " ";
        }
        cout << endl;
    }
}
// пример обработки - подсчет сумм в каждой строке
void Work(int** M,int n,int m)
{
    for(int i=0;i<n;i++)
    {
        int sum=0;
        for(int j=0;j<m;j++)
        {
             sum+=M[i][j];
        }
        cout<<i<<" sum = " << sum<< endl;
    }
}
// сюда вставить все дополнительные функции которые напишете
Примечание:
Цитата Сообщение от MrGluck Посмотреть сообщение
Для system нет ctsdlib, может возникнуть ошибка.
Если тип данных не int - нужно переделывать все функции!
Если ввод/вывод необходимо сделать из файла или просто поменять что-то при вводе/выводе, нужно переписывать функции Input, Print и main.
Если под Linux, то локаль такая не прокатит, команду pause тоже не найдет.
Если выделение памяти нужно сделать по другому, то тоже нужно переписать Create и Free.
Если всё вместе, то нужно переписывать тупо ВСЁ.
А если "мы еще функции не учили", то "образец" вообще глубоко в заднице окажется.
6
zss
Модератор
Эксперт С++
7482 / 6851 / 4324
Регистрация: 18.12.2011
Сообщений: 18,122
Завершенные тесты: 1
10.03.2015, 12:06  [ТС] 3
2. Образец для одномерного массива (вектора)
C++
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
#include <iostream>
//#include <clocale>
#include <cstdlib>
using namespace std;
//----- объявление прототипов используемых функций----------------------------------------
void Input(int* M,int n);  // ввод массива
void Print(int* M,int n);   // вывод массива
void RandomFill(int* M,int n);   // заполнение массива случайными числами
//--------------------------------------------------------------------------
int Work(int* M,int n);   // пример обработки массива
//   Сюда добавить протопипы тех функций которые дополнительно напишете
//--------------------------------------------------------------------------
 
//----------  main() -  точка входа в программу консольного приложения 
int main()
{
    //setlocale(LC_ALL,"Rus");
    int n;
    cout<<"Размер вектора?";
    cin>>n;
    int* A=new int[n];
    //Input(A,n);
    RandomFill(A,n);
    Print(A,n); 
    int s=Work(A,n);
    cout<<"Summa = " << s<< endl;
    delete[] A;
    //system("pause");
    return 0;
}
//----   описание функций -----------------------------------------
// ввод массива
void Input(int* M,int n)
{
    for(int i=0;i<n;i++)
    {
        cout<<"M["<<i<<"]=?";
            cin >> M[i];
    }
}
// заполнение случайными числами
void RandomFill(int* M,int n)
{
    for(int i=0;i<n;i++)
    {
        M[i]=rand()%100;
    }
}
  // вывод массива
void Print(int* M,int n)
{
    for(int i=0;i<n;i++)
    {
        cout << M[i]<< " ";
    }
    cout << endl;
}
// пример обработки - подсчет суммы элементов
int Work(int* M,int n)
{
    int sum=0;
    for(int i=0;i<n;i++)
    {
        sum+=M[i];
    }
    return sum;
}
// сюда вставить все дополнительные функции которые напишете
5
zss
Модератор
Эксперт С++
7482 / 6851 / 4324
Регистрация: 18.12.2011
Сообщений: 18,122
Завершенные тесты: 1
17.03.2015, 23:25  [ТС] 4
Образец для создания классов
Иллюстрирует создание базового и производного класса,
а также применение виртуальной функции
и перегрузку потоковых операторов << >>
C++
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <cstring>
using namespace std;
 
class AA
{
private:
    // здесь данные и методы, которые используются только в базовом классе
protected:
    // здесь данные и методы, которые доступны в производном классе
char* str; // для примера строка с динамически выделяемой памятью
public:
    virtual ~AA(){delete[] str;} // деструктор
    AA(){str=new char[1];*str=0;} // конструктор по умолчанию
    AA(char* x)     // конструктор с параметрами
    {
        str=new char[strlen(x)+1];
        strcpy(str,x);
    }
    AA(const AA& a)  // копиконструктор
    {
        str=new char[strlen(a.str)+1];
        strcpy(str,a.str);
    }
    AA& operator=(const AA& a)  // operator= (правило ТРЕХ)
    {
        if(this==&a)  // обязательно проверяем, что нет присвоения типа x=x;
            return *this;
        if(strlen(str)!=strlen(a.str))
        {
            delete[] str;
            str=new char[strlen(a.str)+1];
        }
        strcpy(str,a.str);
        return *this;
    }
    virtual void f(){cout<<" class A\n";} // виртуальная функция
    friend ostream& operator<<(ostream& os,const AA& a); // перегрузка потокового вывода
    friend istream& operator>>(istream& os,AA& a); // перегрузка потокового ввода
};
//-----------------------------------------------------
ostream& operator<<(ostream& os,const AA& a)
{
    os<<a.str<<endl;
    return os;
}
istream& operator>>(istream& is,AA& a)
{
    char tmp[100];
    is.getline(tmp,100);
    delete[] a.str;
    a.str=new char[strlen(tmp)+1];
    strcpy(a.str,tmp);
    return is;
}
//-----------------------------------------------------
 
class BB : public AA
{
private:
    int SIZE; // дополнительные данные
public:
    ~BB(){}
    BB():AA(){SIZE=strlen(str);}
    BB(char* x):AA(x){SIZE=strlen(str);} // обязательно вызываем конструктор базового класса
    BB(BB& a):AA(a){SIZE=strlen(str);} // обязательно вызываем конструктор базового класса
    BB& operator=(const BB& a)  
    {
        if(this==&a)
            return *this;
        if(SIZE!=a.SIZE)
        {
            delete[] str;
            str=new char[SIZE+1];
        }
        strcpy(str,a.str);
        return *this;
    }
    void f(){cout<<" class B\n";}
    friend ostream& operator<<(ostream& os,const BB& a);
    friend istream& operator>>(istream& os,BB& a);
 
};
//-----------------------------------------------------
ostream& operator<<(ostream& os,const BB& a)
{
    os<<a.str<<" Size="<<a.SIZE<<endl;
    return os;
}
istream& operator>>(istream& is,BB& a)
{
 
    char tmp[100];
    is.getline(tmp,100);
    delete[] a.str;
    a.SIZE=strlen(a.str);
    a.str=new char[a.SIZE+1];
    strcpy(a.str,tmp);
    return is;
}
//----------------------------------------------------- 
int main() 
{
    char tst[]="Hello";
    AA a(tst);  // базовый класс
    a.f();      // невиртуальный вызов f() из AA
    AA a2;
    a2=a;  // operator=
    cout<<a2;
    
    BB b(tst);  // производный класс
    b.f();      // невиртуальный вызов f() из BB
    BB b2=b;    // копиконструктор эквивалентно BB b2(b);
    cout<<b;  
 
    AA* pa; 
// Указателю на базовый класс присваиваем адрес ПРОИЗВОДНОГО класса:
    pa=&b;   
    pa->f();// виртуальный вызов f() из B
    pa->AA::f();// невиртуальный вызов f() из AA
 
    //system("pause");
    return 0;
}
6
castaway
Эксперт С++
4934 / 3039 / 455
Регистрация: 10.11.2010
Сообщений: 11,119
Записей в блоге: 10
Завершенные тесты: 1
18.03.2015, 20:53 5
Образец для двумерного массива
C++
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <iostream>
#include <clocale>
#include <cstdlib>
#include <ctime>
//
// Создание матрицы
//
int ** Create( size_t n, size_t m ) {
    int ** M = new int * [n];
    for ( size_t i = 0; i < n; ++i ) {
        M[i] = new int [m];
    }
    return M;
}
//
// Удаление матрицы
//
void Free( int ** M, size_t n ) {
    for ( size_t i = 0; i < n; ++i ) {
        delete [] M[i];
    }
    delete [] M;
}
//
//---- ввод матрицы--------------------------------------
//
void Input( int ** M, size_t n, size_t m ) {
    for ( size_t i = 0; i < n; ++i ) {
        for ( size_t j = 0; j < m; ++j ) {
            std::cout << "M[" << i << "][" << j << "] = ";
            std::cin >> M[i][j];
        }
    }
}
//
// заполнение матрицы случайными числами из диапазона [0, 99] -----------
//
void FillRandomNumbers(int **matrix, const size_t rows, const size_t columns)
{
    srand((unsigned int)time(0)); // инициализируем ПГСЧ
 
    for (size_t row=0; row < rows; row++)
        for (size_t column=0; column < columns; column++)
            matrix[row][column] = rand() % 100; // присваиваем СЧ
}
//
//-------- Печать матрицы ------------------------------------------------
//
void Print( int ** M, size_t n, size_t m ) {
    for ( size_t i = 0; i < n; ++i ) {
        for ( size_t j = 0; j < m; ++j ) {
            std::cout<<M[i][j]<<' ';
        }
        std::cout<<std::endl;
    }
}
//
// пример обработки матрицы - подсчет сумм в каждой строке
//
void Process( int ** M,int *Sum, size_t n, size_t m ) {
    for ( size_t i = 0; i < n; ++i ) {
        Sum[i] = 0;
        for ( size_t j = 0; j < m; ++j ) {
            Sum[i] += M[i][j];
        }
    }
}
 
// ...
// сюда вставить все дополнительные функции которые напишете
// ...
 
int main()
{
    //setlocale( LC_ALL, "Rus" ); // установление русской локали (windows)
 
    size_t n, m;
 
    // вводим размерность матрицы
    std::cout << "Введите количество строк матрицы: ";
    std::cin >> n;
    std::cout << "Введите количество столбцов матрицы: ";
    std::cin >> m;
 
    // выделяем память под матрицу
    int ** A = Create( n, m );
 
    // ввод матрицы
    //Input( A, n, m );
    // заполнение случайными числами (вместо ввода)
    FillRandomNumbers(A,n,m);
 
    // обработка матрицы
    int* S=new int[n]; // Вектор результата
    Process( A, S, n, m );
 
    // вывод результата
    for(size_t i=0;i<n;i++) 
        std::cout<< S[i] <<' ';
    std::cout<<std::endl;
 
    // Вывод матрицы
    Print(A,n,m);
 
    // освобождаем память, выделенную под матрицу и вектор
    delete[] S;
    Free( A, n );
 
    // ждём нажатия клавиши перед выходом из приложения (windows)
    //system( "pause" );
 
    return 0;
}
5
MrGluck
Модератор
Эксперт CЭксперт С++
8105 / 4957 / 1436
Регистрация: 29.11.2010
Сообщений: 13,451
18.03.2015, 21:31 6
Мой Hello world на тему матриц:
C++
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
72
73
74
75
76
77
78
//#include <clocale>
#include <cstdlib>
#include <ctime>
#include <iostream>
 
/// заполнение матрицы случайными числами из диапазона [0, 99]
void FillRandomNumbers(int **matrix, const size_t rows, const size_t columns)
{
    srand(time(0)); // инициализируем ПГСЧ
 
    for (size_t row=0; row < rows; row++)
        for (size_t column=0; column < columns; column++)
            matrix[row][column] = rand() % 100; // присваиваем СЧ
}
 
/// вывод матрицы на экран
void Print(int **matrix, const size_t rows, const size_t columns)
{
    for (size_t row=0; row < rows; row++)
    {
        for (size_t column=0; column < columns; column++)
            std::cout << matrix[row][column] << " "; // выводим элемент
        std::cout << std::endl; // перевод строки
    }
}
 
/// пример обработки матрицы - подсчет суммы всех элементов
int Sum(int **matrix, const size_t rows, const size_t columns)
{
    int sum = 0; // счётчик суммы
    for (size_t row=0; row < rows; row++)
        for (size_t column=0; column < columns; column++)
            sum += matrix[row][column];
 
    return sum; // вернуть результат
}
 
// ...
// сюда вставить все дополнительные функции которые напишете
// ...
 
 
int main()
{
    //setlocale(LC_ALL, "rus"); // установим локаль для вывода русских символов
 
    size_t rows, columns; // строки и столбцы
 
    // вводим размерность матрицы
    std::cout << "Введите количество строк матрицы: ";
    std::cin >> rows;
    std::cout << "Введите количество столбцов матрицы: ";
    std::cin >> columns;
 
    // выделяем память под матрицу
    int **matrix = new int*[rows];
    for (size_t row=0; row < rows; row++)
        matrix[row] = new int[columns];
 
    // заполнение случайными числами
    FillRandomNumbers(matrix, rows, columns);
 
    // вывод на экран
    std::cout << "\nМатрица:\n";
    Print(matrix, rows, columns);
 
    // обработка матрицы
    std::cout << "\nСумма всех элементов матрицы равна " << Sum(matrix, rows, columns) << std::endl;
 
    // освобождаем память, выделенную под матрицу
    // освобождение идёт в обратном порядке от выделения
    for (size_t row=0; row < rows; row++)
        delete[] matrix[row];
    delete[] matrix;
 
    // ждём нажатия клавиши перед выходом из приложения
    //system("pause");
}
4
JavaUser
70 / 70 / 28
Регистрация: 06.10.2013
Сообщений: 309
08.04.2015, 15:01 7
Пример программы для работы с массивом структур. Программа позволяет вводить данные в массив, отображать отсортированную информацию и осуществлять поиск в структуре.
C++
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <cstdlib>
using namespace std;
/**Определение структуры**/
struct SOTRUDNIK
{
    char SotFam[255];   //Фамилия сотрудника
    char SotName[255];  //Имя сотрудника
    short SotStag;      //Стаж сотрудника
    short SotAge;       //Возраст сотрудника
    char SotSex;        //Пол сотрудника
};
/**Вспомогательная процедура для обмена местами двух элементов**/
void swapvalue(SOTRUDNIK &s1,SOTRUDNIK &s2)
{
    SOTRUDNIK temp=s1;
    s1=s2;
    s2=temp;
}
/**Процедура вывода на экран информации.*
* параметр "param" указывает то, сотрудников каких возрастов выводить. Если параметр не указан, то выводятся все сотрудники
*/
void ShowInfo(SOTRUDNIK *sot, int N,short param=0)
{
    int col=0;      //вспомогательная переменная, описывающая кол-во найденных сотрудников указанного возраста
    if(param==0)
    {
        for(int i=0;i<N;i++)
        {
            for(int j=1;j<N-1;j++)
            {
                if(sot[i].SotStag<=sot[j].SotStag)
                    swapvalue(sot[i],sot[j]);
            }
        }
        cout<<"___INFO ABOUT ALL:___\n";
        for(int i=0;i<N;i++)
        {
            cout<<"FAMILIA: "<<sot[i].SotFam<<"\n";
            cout<<"NAME: "<<sot[i].SotName<<"\n";
            cout<<"STAG: "<<sot[i].SotStag<<"\n";
            cout<<"AGE: "<<sot[i].SotAge<<"\n";
            cout<<"POL: "<<sot[i].SotSex<<"\n";
        }
    }
    else
    {
        cout<<"___INFO ABOUT PEOPLE WITH AGE= "<<param<<":___\n";
        for(int i=0;i<N;i++)
        {
            if(sot[i].SotAge==param)
            {
                cout<<"FAMILIA: "<<sot[i].SotFam<<"\n";
                cout<<"NAME: "<<sot[i].SotName<<"\n";
                cout<<"STAG: "<<sot[i].SotStag<<"\n";
                cout<<"AGE: "<<sot[i].SotAge<<"\n";
                cout<<"POL: "<<sot[i].SotSex<<"\n";
                col++;
            }
        }
        if(col<1)
            cout<<"******NO INFO\n";
    }
}
/**Процедура ввода информации**/
void SetInfo(SOTRUDNIK *sot, int N)
{
    for(int i=0;i<N;i++)
    {
        cout<<"------------------\n";
        cout<<"FAMILIA:";cin.getline(sot[i].SotFam,255);cin.ignore();
        cout<<"NAME:";cin.getline(sot[i].SotName,255);cin.ignore();
        cout<<"STAG:";cin>>sot[i].SotStag;
        cout<<"AGE:";cin>>sot[i].SotAge;
        cout<<"POL:";cin>>sot[i].SotSex;cin.ignore();
    }
}
int main()
{
    int N=8;
    SOTRUDNIK *sotr=new SOTRUDNIK[N];
    SetInfo(sotr,N);
    ShowInfo(sotr,N);
    delete[]sotr;
    return 0;
}
1
MrGluck
Модератор
Эксперт CЭксперт С++
8105 / 4957 / 1436
Регистрация: 29.11.2010
Сообщений: 13,451
08.04.2015, 21:31 8
Цитата Сообщение от JavaUser Посмотреть сообщение
Пример программы для работы с массивом структур.
Ужасный код стайл.
Не хватает пробелов в конструкциях.
char массивы - пережиток С. Здесь С++, соответственно std::string.
Magic number.
Транслит в образце типовых задач? Вы серьёзно?
Код не говорит сам за себя. Ужасные имена переменных. Что за неочевидный param?
Несколько инструкций на одной строке.
Не хватает вертикальных отступов.
Почему не vector?
Почему нет const где он требуется?
5
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16756 / 6647 / 865
Регистрация: 12.06.2012
Сообщений: 19,897
Завершенные тесты: 1
08.04.2015, 22:10 9
Цитата Сообщение от MrGluck Посмотреть сообщение
Ужасный код стайл.
+различные именования функций - вроде как CamelCase, но нет (swapvalue, но ShowInfo/SetInfo)
и название структуры прописными буквами, аж по глазам бьет..
0
Max Dark
шКодер самоучка
1970 / 1746 / 861
Регистрация: 09.10.2013
Сообщений: 3,855
Записей в блоге: 6
Завершенные тесты: 2
08.07.2015, 11:01 10
велосипедный стек на односвязном списке
C++
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
72
73
74
75
76
77
78
79
80
81
82
83
// сборка: g++ -std=c++11 stack.cxx -o stack
#include <stdexcept>
#include <exception>
#include <iostream>
 
// шаблонный стек на основе односвязного списка
template<class Type>
class stack {
public:
    typedef Type value_type; // тип значения
    typedef value_type& value_ref; // ссылка на элемент
    typedef const value_type& value_cref; // константная ссылка
private:
    // структура "звено"
    struct node {
        value_type value; // значение
        node* link;  // указатель на следующий
        // конструктор по умолчанию
        node():value(0),link(nullptr){}
        // конструктор с установкой значений
        node(value_cref val, node* prev):value(val),link(prev){}
    };
    node*  m_head; // голова стека
public:
    // конструктор по умолчанию
    stack():m_head(nullptr),m_size(0){}
    // деструктор
    ~stack() { clear(); }
    // проверка на пустоту
    bool is_empty() { return nullptr == m_head; }
    // очистка стека
    void clear() {
        while(not is_empty()) {
            node* tmp = m_head;
            m_head = m_head->link;
            delete tmp;
        }
    }
    // возвращает значение на верхушке стека
    value_ref top() {
        if(is_empty())
            throw std::runtime_error("stack is empty");
        return m_head->value;
    }
    // добавление элемента
    void push(value_cref value) {
        // создаем звено
        node* tmp = new node(value, m_head); // при нехватке памяти
                                             // будет выброшено исключение std::bad_alloc
        // запоминаем новую голову
        m_head = tmp;
    }
    // удаляет верхний элемент
    void pop() {
        if(is_empty())
            throw std::runtime_error("stack is empty");
        // запоминаем голову
        node* tmp = m_head;
        // смещаемся к следующему
        m_head = m_head->link;
        // удаляем старую голову
        delete tmp;
    }
};
int main() {
    stack<int> st; // создаем стек
    // записываем данные
    for(int i = -5; i <= 5; ++i) {
        try {
            st.push(i);
        }
        catch(std::bad_alloc &e) {
            std::cerr << "Oops: " << e.what() <<std::endl;
            return 1;
        }
    }
    // выводим содержимое
    while(!st.is_empty()) {
        std::cout << st.top() << std::endl;
        st.pop();
    }
    return 0;
}
0
Croessmah
++Ͻ
14777 / 8453 / 1605
Регистрация: 27.09.2012
Сообщений: 20,803
Записей в блоге: 2
Завершенные тесты: 1
16.07.2015, 21:02 11
Cra3y, всё же, я бы втыкнул сюда const:
C++
1
bool is_empty() const { /*...*/ }
и константная версия top не помешает
1
Fallenworld
76 / 76 / 32
Регистрация: 14.04.2014
Сообщений: 408
17.07.2015, 18:32 12
Работа с памятью
0
Mr.X
Эксперт С++
3183 / 1710 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
17.07.2015, 20:53 13
Базовый класс для любого конечного автомата.
0
castaway
Эксперт С++
4934 / 3039 / 455
Регистрация: 10.11.2010
Сообщений: 11,119
Записей в блоге: 10
Завершенные тесты: 1
03.11.2015, 13:35 14
Вычисление значения кусочно заданной функции
http://www.cyberforum.ru/cgi-bin/latex.cgi?y=\left\{\begin{matrix}({x}^{2}-3)-\sqrt[3]{\pi -x},x<0 \\ {({x}^{2}+3)}^{2}-\sqrt{0,5\pi +x},0\leq x < 1 \\ x({x}^{2}+3)+\ln(\pi +x),x\geq 1\end{matrix}\right.
C++
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
#include <iostream>
#include <cmath>
#include <cstdlib>
double f(double x)
{
   double y;
    const double pi = 3.1415926535897932384626433832795;
 
    if ( x < 0 ) {
        // x < 0
        y = x * x - 3 - std::pow( pi - x, 1. / 3 );
    } else {
        double x2 = x * x + 3;
        if ( x >= 1 ) {
            // x >= 1
            y = x * x2 + std::log( pi + x );
        } else {
            // 0 <= x < 1
            y = x2 * x2 - std::sqrt( pi / 2 + x );
        }
    }
   return y;
}
 
int main()
{
    double x;
    std::cout << "Введите x: ";
    std::cin >> x;
 
    std::cout << "y = " << f(x) << std::endl;
    std::system( "pause" );
    return 0;
}
2
macewindujedii
5 / 5 / 2
Регистрация: 20.11.2015
Сообщений: 9
04.12.2015, 23:30 15
Функция с переменным числом параметров
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
double kek(int n,double x,...);  // прототип функции
int main()
{
    std::cout <<"S="<<kek(8, 0.1, 0.2, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0)<<std::endl;
    //system("pause");
    return 0;
}
 
double kek(int n,double x,...)  // функция вычисляющая сумму параметров, первое число - их количество
{
   double* p = &x;    //установились на начало списка параметров
   double s = 0;
   for(int i=0;i<n;i++)
       s+=*(p++);
   return s;
}
комментарий Tulosba
Попытки работать с функцией с переменным числом параметров без явного использования типов и макросов из <cstdarg> не является переносимыми.
Например, указанный код не работает должным образом на не MS-компиляторах.
Предлагаю удалить из темы этот пример кода как вводящий в заблуждение и несоответствующий реалиям.
P.S. В современном C++ вместо семейства va_* из <cstdarg> следует использовать variadic templates.
1
Tulosba
:)
Эксперт С++
4750 / 3244 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
07.12.2015, 12:08 16
Пример вычисления суммы чисел функцией с переменным числом аргументов при помощи variadic templates (c++11):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
// терминальная функция
double sum() { return 0; }
 
// функция с переменным числом аргументов
template <typename... R> 
double sum(double init, R... rest) {
    return init + sum(rest...);
}
 
int main() {
    // кол-во аргументов может быть любым 
    std::cout << sum(1, 2.1, 3, -1.5) << std::endl;
}
1
Tulosba
:)
Эксперт С++
4750 / 3244 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
08.12.2015, 12:37 17
Хотелось бы добавить, что для гомогенных аргументов не следует прибегать к variadic templates, а лучше использовать std::initializer_list:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <initializer_list>
#include <iostream>
 
double sum(std::initializer_list<double> lst) {
    double res = 0; // лучше использовать std::accumulate
    for(double el : lst) {
        res += el;
    }
    return res;
}
 
int main() {
    std::cout << sum({1, 2.1, 3, -1.5}) << std::endl;
}
4
Avazart
Эксперт С++
7759 / 5664 / 555
Регистрация: 10.12.2010
Сообщений: 25,675
Записей в блоге: 17
31.01.2016, 14:01 18
Cra3y, И assert вместо исключений.
1
Nikitko_Cent
144 / 114 / 37
Регистрация: 27.10.2011
Сообщений: 690
Завершенные тесты: 3
09.03.2016, 03:14 19
Одно из применений идиомы CRTP : статический полиморфизм (не путать с параметрическим) a.k.a "динамический полиморфизм без виртуальных методов"
Ещё одна плюшка - организация поведения статических методов по типу виртуальных.

C++
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
72
73
74
75
76
77
78
#include <iostream>
 
template <typename T>
class BinaryOperationBase
{
public:
    static double run(double left, double right)
    {
        return T::run(left, right);
    }
 
    void saveResult(double left, double right)
    {
        static_cast<T *>(this)->saveResult(left, right);
    }
 
    double getResult()
    {
        return static_cast<T *>(this)->getResult();
    }
};
 
class DoubleMult : public BinaryOperationBase<DoubleMult>
{
private:
    double result;
public:
    static double run(double left, double right)
    {
        return left * right;
    }
 
    void saveResult(double left, double right)
    {
        result = left * right;
    }
 
    double getResult()
    {
        return result;
    }
};
 
class DoubleSub : public BinaryOperationBase<DoubleSub>
{
private:
    double result;
public:
    static double run(double left, double right)
    {
        return left - right;
    }
 
    void saveResult(double left, double right)
    {
        result = left - right;
    }
 
    double getResult()
    {
        return result;
    }
};
 
int main()
{
    BinaryOperationBase<DoubleMult> *mult = new DoubleMult();
    BinaryOperationBase<DoubleSub> *sub = new DoubleSub();
 
    std::cout << BinaryOperationBase<DoubleMult>::run(20.5, 10.0) << '\n';  
    std::cout << BinaryOperationBase<DoubleSub>::run(20.5, 10.0) << "\n\n"; 
 
    mult->saveResult(-120.3, -3.3);
    sub->saveResult(-120.3, -3.3);
    std::cout << mult->getResult() << ' ' << sub->getResult() << "\n\n";
 
    return 0;
}
В примере рассмотрена реализация и статических и обычных методов классов, используя CRTP
0
obivan
Падаван С++
425 / 243 / 84
Регистрация: 11.11.2014
Сообщений: 876
Завершенные тесты: 2
01.05.2016, 20:23 20
Пример вычисления последовательности Фибоначи на шаблонах
C++
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
#include <iostream>
 
namespace Constants {
    const size_t FibSize = 32;
}
 
template<int t> struct Elem {
    static const size_t value = Elem<t - 1>::value + Elem<t - 2>::value;
};
template<> struct Elem<0> {
    static const size_t value = 0;
};
template<> struct Elem<1> {
    static const size_t value = 1;
};
template<int r, int t> struct Table : Table<r + 1, t - 1> {
    Table() { values[t] = Elem<t>::value; }
};
template<int r> struct Table<r, 0> {
    size_t values[r + 1];
    Table() { values[0] = Elem<0>::value; }
    const size_t& operator[](int i) const { return values[i]; }
};
 
typedef Table<0, Constants::FibSize> Fibonachi;
 
int main(int argc, char *argv[]) {
    Fibonachi fArray;
 
    for (size_t i(0); i < Constants::FibSize; ++i)
        std::cout << fArray[i] << std::endl;
 
    std::cin.ignore();
    return 0;
}
1
01.05.2016, 20:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.05.2016, 20:23

«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами».
«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами». Есть ли разница в...

Шаблоны. Плохо понимаемые моменты из книги "Шаблоны С++. Справочник разработчика". (Вандевурд, Джосаттис)
Так как изучаю эту книгу, то в некоторых местах возникают вопросы. Чтобы не...

Помогите писать на С++ через шаблоны. Консуле я писал, но надо писать исползуя шаблоны
В одномерном массиве, состоящем из п вещественных элементов, вычислить: 1)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru