Д.з. на 7 апреля Язык С++1
Задача 1: * и *= для rational class rational { int num, den; public: rational(int num_=0, int den_=1) : num(num_), den(den_) {} rational& operator*=(rational r) { num *= r.num; den *= r.den; return *this; } Умолчания для конструктора? O / 1 Что определять? * через *= *= через * Язык С++2
Задача 1: * и *= для rational rational operator*(rational r1, rational r2) { rational res = r1; res *= r2; return res; } // Тут operator* можно не описывать // как friend! // Пример вызова rational r2(2, 3); r1 *= r2; rational r3 = r1*r2; Язык С++3
Задача 2: rational double class rational {... operator double() const { return double(num)/den; } }; // Пример вызова rational r(1,3); double x = r;// x = Еще желательно проверять, что знаменатель не равен 0 Язык С++4
Задача 4: first_last_spaces Как вернуть два значения? Через доп. параметры по ссылке void first_last_spaces(const char* s, int& first, int& last) { first = -1; second = -1; for (const char* p=s; *p!='\0'; p++) { if (*p == ' ') { if (first==-1) { first = p-s; } last = p-s; } } } // Пример вызова char s[100]; cin >> s; int i, j; first_last_spaces(s, i, j); cout
Задача 4: first_last_spaces pair first_last_spaces( const char* s) { int first = -1; int second = -1; for (const char* p=s; *p!='\0'; p++) { if (*p == ' ') { if (first==-1) { first = p-s; } last = p-s; } } return pair (first, second); } // Пример вызова: char s[100]; cin >> s; pair p = first_last_spaces(s); cout
Д.з. на 14 апреля Язык С++7
Задача 2: подсчет объектов class abc { static int cnt; public: abc() { cnt++; } ~abc() { cnt--; } abc(const abc& from) { cnt++; // Это важно } // на забыть! static int num () { return cnt; } }; int abc::cnt = 0; // Ппимер вызова abc x; abc y; cout
Задача 3: atoi_oct – алгоритм Вариант 1 for (int i = …; i Очень неэффективно! Вариант 2 Схема Хорнера Язык С++99
Задача 3: atoi_oct int atoi_oct(const char* s) { int res = 0; for (const char* p = s; *p != '\0'; p++) { res = res*8 + *p - '0';// Схема Хорнера } return res; } // Пример вызова char s[100]; cin >> s; int i = atoi_oct(s); // Вводим 104, получаем i = 68; Язык С++10
Задача 4: числа в обратном порядке list l; // Вариант с list // Добавляем в обратном // порядке while (f >> n) { // Читаем l.push_front(n); } // Печатаем list ::iterator p; for (p=l.begin(); p!=l.end(); p++) { cout n) { v.push_back(n); } // Идем от конца к началу for (int i=v.size()-1; i >= 0; i--) { cout
Задача 4: числа в обратном порядке vector v; // Вариант с // vector и итератором while (f >> n) { v.push_back(n); } // Идем от конца к началу vector ::iterator p = v.end(); do { p--; cout
Задача 4: числа в обратном порядке Какой вариант лучше? Для больших объемов list гораздо медленнее! list – только если надо часто добавлять в середину (или удалять)
Разные замечания Язык С++14
Типичные ошибки void f(string s) Лучше void f(const string& s) ! void f(const int i) Лучше void f(int i) ! for (int i = 0; i
Еще про list и vector. deque Язык С++16
Дополнительные возможности На экзамене не будет Для всех контейнеров: присваивание v = v1; сравнение if (v == v1) лексикографическое сравнение if (v < v1) можно менять местами swap(v, v1); // Эффективно Только для vector reserve v.reserve(1000); Язык С++17
Еще про итераторы Итераторы для вектора Те же операции (++ и т.д.) p + n p – n p += n p -= n Итераторы и константы const_iterator void f(const vector & v) { // Тут просто итераторы // использовать нельзя vector ::const_iterator p =v.begin(); …
Вставка и удаление insert l.insert(p, n); Вставляет перед p Работает быстро (время O(1) (T.е. не зависит от длины списка) Работает и для vector, но для vector время О(n) erase l.erase(p); Тоже О(1) для списков и О(n) для векторов Язык С++19
deque = (примерно) vector + push_front/pop_front Язык С++20
Ассоциативные контейнеры Язык С++21
set (множество) #include using namespace std; set s; s.insert(11); s.insert(3); s.insert(7); Если уже есть, не добавляется s.insert(3); // ничего не делает Удаление s.erase(i); // Удалить (если есть) Печать set :: iterator p; for (p = s.begin(); p!= s.end(); p++) cout
set - продолжение Поиск s.find(i) p = s.find(i); if (p == s.end() ) cout
Пример работы с set // Вводим числа и печатаем в порядке возрастания #include using namespace std;... set s; int n; while ( cin >> n )// Читаем до первой ошибки ввода s.insert(n);// И добавляем в set // Распечываем. Будет напечатано в порядке возрастания. set ::iterator p; for (p = s.begin(); p != s.end(); p++) cout
map (ассоциативный массив) #include using namespace std; map m; m[3.14] = 55; m[2.238] = 73; m[9.0] = 15; cout
map – продолжение 1 Печать map ::iterator p; for (p = s.begin(); p != s.end(); p++) cout first second ) Итератор указывает на структуру pair(пара): Структура с полями first, second Очень примерно: map – это set, составленый из пар. Поиск p = m.find(i); if (p == m.end() ) cout
map – продолжение 2 insert Можно добавить пару Чтобы задать пару, есть очень простая функция (точнее, шаблон) make_pair m.insert(make_pair(i, x)); Язык С++27
Пример работы с map // Вводим пары чисел и печатаем их в порядке возрастания // первого числа #include using namespace std;... map m; double x; int i; while ( cin >> x >> j ) m[x] = j;// или можно то же записать, как // m.insert(make_pair(x, j)); map ::iterator p; for (p = m.begin(); p != m.end(); p++) cout first second
Еще пример – телефонная книга #include using namespace std; // Определим тип phonebook – // телефонная книга typedef map phonebook; phonebook pb;// Тел. книга // (вначале она пустая) // Так задаются значения pb["Иванов"] = ; pb["Петров"] = ; pb["Сидоров"] = ; // Печатаем телефон Петрова cout
Tелефонная книга - продолжение // Так можно проверить, есть ли человек в тел.книге if ( pb.find("Smith") != pb.end() ) { cout
Как вернуть массив из функции? Язык С++31
Как вернуть массив из функции? (неудачные варианты) Так не получится: int *f() { int a[100]; … return а; // Очень плохо! } Так тоже плохо: int* f() { int* p = new int[…]; … return p; } Кто будет освобождать память, которую мы отвели? Язык С++32
Как вернуть массив из функции? (варианты получше) Передавать, как параметр void f(int* a) { // Как-то заполняем массив … a[i] = … ; … } // Пример вызова int b[100]; f(b); Возвращать vector (или string) Вернуть статическую переменную int f() { static int a[100]; … как-то заполняем… return a; } OK, так можно, но результат функции лучше не запоминать надолго! Язык С++33
Библиотека MFC. Рисование в Windows программах. Все за 10 минут. Язык С++34
Создание MFC программы 1. Ряд заклинаний (инструкция на сайте) Получится рабoтающая программа (которая пока ничего не делает). 2. Найти место, куда вписать свой код CAbcView::OnDraw(CDC* pDC) { // TODO Язык С++35
Рисование в MFC CDC* pDC- device context pDC->Ellipse(x1, y1, x2, y2); pDC->MoveTo(x, y); pDC->LineTo(x, y); Язык С++36
Задачи на 21 апреля Язык С++37
Задачи на 21 апреля itoa_oct – целое положительн. число строка, содержащая запись числа в восьмеричной системе счисления. Интерфейс придумайте, пожалуйста сами. 2. (Простое упражнение) Описать тип (типы?) для телефонной книги: имя телефон, имя, адрес (день рождения?). Привести пример работы с таким типом. 3. Частотный словарь. Ввести из файла слова, и сосчитать, какое из их сколько раз встречалось. Например: to be or not to be. be – 2 not – 1 or – 1 to – 2 Подсказка: map Напоминание – как вводить слова: #include string s; while (f >> s) { … } Язык С++38
Задачи на 21 апреля MFC - вложенные треугольники (соединяем середины сторон). Сколько треугольников – как хотите, фиксированное количество, или пока очередной не станет очень маленьким. 5. MFC – треугольник Серпинского (если сделана задача 5 – задачу 4 можно не делать, она зачтется автоматически) Язык С++39