Upload
ketan
View
53
Download
0
Embed Size (px)
DESCRIPTION
Д.з. на 31 марта. Язык С++. 1. Задача 1 : поиск четного. // Поиск четного – без использования исключений bool find_even(const tree* p) { if ( p ==0) // В пустом дереве нет return false ; // четных элем e нтов return // А для не пустого используем - PowerPoint PPT Presentation
Citation preview
Д.з. на 31 марта
Язык С++ 1
Задача 1: поиск четного// Поиск четного – без использования исключений
bool find_even(const tree* p){ if (p==0) // В пустом дереве нет return false; // четных элемeнтов
return // А для не пустого используем p->val%2 == 0 || // рекурсивную формулу.
find_even(p->left) || find_even(p->right);}
Задача 1: поиск с исключениями Что бросать?
Вариант: Указатель на вершину
void find_even1(const tree* p){ if (p!=0) // Для пустого дерева return; // ничего не делаем
if (p->val % 2 ==0) // Нашли? throw p; // бросаем указатель
// на вершину
// Иначе обходим поддеревья find_even1(p->left); find_even1(p->right);}
// find_even - вызываем find_even1 и// смотрим, было ли исключение.
bool find_even(const tree* p){ try { find_even1(p); } catch (const tree* p) {
return true; } return false;}
Плохой стиль? (исключения только для обработки ошибок?)
Язык С++ - занятие 7 33
Задача 4: сравнение строк без учета пробелов// Oдин из многих возможных способов решения..bool compare(const char* s1, const char* s2){
for (;;) { // Пропускаем пробелы while (*s1==' ') s1++; while (*s2==' ') s2++;
if (*s1!=*s2) // Разные символы? Выходим из цикла break;
if (*s1=='\0') // Конец обеих строк? return true;
s1++; s2++;}
return false; // Раз мы здесь, то строки не равны}
Задача 3: исключения и утечка памяти// Исходная функция// … что-то делает со стеком
…// Если стек пуст –
исключение
void f(stack& s){ int* p = new int[1000]; … что-то делаем с p … cout << s.pop(); delete [] p;}
// Если стек пуст - // утечка памяти
// Вариант 1:
void f(stack& s){ int* p = new int[1000]; … что-то делаем с p … try { cout << s.pop(); } catch (…) { } delete [] p;} // Если стек пуст, об // этом никак не
сообщается
Задача 3: еще вариант// Вариант 2:void f(stack& s){ int* p = new int[1000]; … что-то делаем с p … try { cout << s.pop(); } catch (…) { delete [] p; throw; } delete [] p;} // Слишком сложно? // Использовать RAII?
Задача 3: еще вариант – "обернуть" p в класс!// Вариант 3:class wrapper { int* p;public: wrapper() { p = new int[1000]; } ~wrapper() { delete[] p;
// Теперь delete точно выполниться } int* get() { return p; }};
void f(stack& s){ wrapper p;
… что-то делаем с p.get() …
cout << s.pop();}
RAIIResource Acquisition Is InitializationПолучение ресурса есть инициализация
Пусть обязательно надо выполнить какое-то действие в конце функции
(удалить память, закрыть файл, восстановить форму курсора и т.д.)
Совет: • завести вспомогательный класс• выполнять это действие в деструкторе
Преимущества:• Получается короче• thread safe – действие будет выполнено даже при наличии
исключений
• Замечание: Если действие – это ‘освободить память’ то можно использовать стандартные классы (vector) или классы boost (scoped_ptr, shared_ptr)
Д.з. на 7 апреля
Язык С++ 9
Задача 3: += для строкПлан действий:1. Отвести новый кусок памяти под длинную строку2. Скопировать туда первую строку3. Дописать вторую строку4. Удалить старый кусок памяти5. Установить новые p и len
Язык С++ 10
Задача 3: += для строкstring& string::operator+=(const string& from)
{
int newlen = len + from.len; // Вычисляем новую длину
char* newp = new char[newlen + 1]; // Создаем новую строку
strcpy(newp, p); // Сначала копируем первую строку
strcpy(newp + len, from.p); // Потом, с нужного места,
// приписываем вторую
delete [] p; // Освобождаем ‘старую’ строку
p = newp; // И устанавливаем новую строку
len = newlen; // И ее длину
return *this;
}
Язык С++ 11
Доп.задачи про списки
Язык С++ 12
Задача 5: список в обратном порядкеstruct list { int val; list* next;
list(int val_, list* next_) :val(val_), next(next_)
{}};
// Переставить элементы в// обратном порядкеvoid reverse(list*& head){
list* head1 = 0; // Как бы создаем
// новый список
list* p = head;
// Цикл по всем элементамwhile (p != 0) { list* next = p->next;
// Элемент добавляем в // начало нового списка p->next = head1; head1 = p;
p = next;}
head = head1;}
Язык С++ 13
Замечания про operator= и конструктор копирования
25.03.2008 Язык С++ 14
Замечания про оператор = и конструктор копирования class abc {
string a, b, c;};
Тут оператор = и конструктор копирования по умолчанию работают правильно. a = from.a; b = from.b; c = from.c;(Вызываются переопределенные операторы =)
Значит, тут оператор = и конструктор копирования лучше не переопределять.
Язык С++ 15
Локальные, глобальные и статические переменные
Язык С++ 16
Какие бывают переменные? Локальная
Внутри функции
void f(){ int a = 56;
ГлобальнаяВне функции
int a = 56;void f(){ …
СтатическаяВнутри функции, static
void f(){ static int a = 56;
Тут на доске была нарисована таблица: для каждого из этих видов переменных – когда они создаются, когда уничтожаются и из какой части программы они видны.
static переменные – это, в каком-то смысле, среднее между локальными и глобальными
Примерint f(){ static int i = 0; i++; return i;}
Язык С++ 18
Статические поля и методы
Язык С++ 19
static методыclass abc {
static void f(int i); …
}
void abc::f(int i){ …}
// Вызовabc::f(56);
Обычные функции(только описанные как бы внутри класса)
Не могут использовать поля класса
Точнее, могут использовать только статические поля
Конечно, не могут быть virtual Могут быть private и protected В методах класса можно писать
просто f(i);
Зачем? По смыслу очень тесно
связанные с классом Вспомогательные (private)Язык С++ 20
static методы - пример// Current time возвращает // текущее время
class time {…
static time current() { … }};
time t = time::current();
Язык С++ 21
static поляclass abc {
static int i; …
}
int abc::i = 0;
// Использование аbc::i = 5;
Обычные глобальные переменные(только описанные как бы внутри класса)
Могут быть private и protected В методах класса можно писать
просто i
Не забывайте объявление int abc::i = 0;
Зачем? По смыслу очень тесно
связанные с классом Вспомогательные (private)
Язык С++ 22
static поля - замечания static const целые можно описывать прямо в классе
class abc {static const int maxsize = 100;…
};
На старых компиляторах это не работает
Можно понимать static поля, как поля, общие для всех членов класса
Язык С++ 23
Что еще может быть в классе, кроме полей и
методов
Язык С++ 24
enum в классеclass card { enum suit {spades, clubs,
hearts, diamonds}; …};
// Использованиеcard::suit s = card::spades;
В методах класса можно писатьпросто:
suit s = spades;
М.б. private/protected
Так часто объявляют константы:
class abc { enum {maxsize = 100}; …
то же, что
class abc { static const int maxsize = 100; …
Язык С++ 25
typedef в классе
class abc { typedef long* myptr;
…};
// Использованиеabc::myptr x; // Вне классаmyptr x; // В классе
М.б. private/protected
Язык С++ 26
Вложенные классыclass abc { class qlm {
int i; void f(); …};…
};
// Определение методовvoid abc::qlm::f(){ … }
// Использованиеabc::qlm x;
В методах класса abc можно писать просто qlm x;
Методы, естественно, можно описывать и прямо в классе
class abc { … void qlm::f() { … }
Cовершенно обычный класс, только с таким странным именем abc::qlm
Применение: вспомогательные классы
Язык С++ - занятие 9 27
Вложенные классы и права доступа (дружба) Стандарт: не друзья
Новый стандарт:внутренние классы могут использовать private поля внешнего класса.
STL – Standard Template Library
Язык С++ 29
Alexander Stepanov
vector#include <vector>using namespace std;
vector<int> v(100);vector<int> v;
vector<double> v1;vector<string> v2;vector<time> v2;vector<vector<int>> v3;
v[i] = 42;v[i] ++;
v.at(i)// то же, что v[i], но с // проверкой диапазона
v.push_back(56);v.pop_back();
int n = v.size()
for (int i = 0; i<v.size(); i++) cout << v[i];
v.resize(200);
Язык С++ - занятие 9 31
list
#include <list>using namespace std;
list<int> l; // Двусторонний список
Некоторые операции, как для вектора:
push_back, pop_back l.push_back(3); l.pop_back();
size n = l.size();
Есть дополнительные операции: push_front, pop_front
l.push_front(5);
Нет: l[i] resize
Язык С++ 32
Итераторы
list<int>::iterator p;
Операции: p = l.begin(); p++; *p; cout << *p; *p = 66; p--; l.end(); // За концом списка
// конец списка:p = l.end() ;p--;
// Пример: сумма элементовsum = 0;for (p = l.begin(); p != l.end(); p++) {
sum += *p;}
Язык С++ 33
Еще про тип char char - это маленькое число
unsigned char 0 – 255 signed char -128 – 127 char зависит от компилятора
Все арифметическиe операции работают
if (c > '0' && c <= '9')
int i = c – '0'; // Переводим символ от ‘0’ до ‘9’ // в соответствующее число
Язык С++ 34
Замечание про то, как вернуть объект из функцииabc f(){
… abc* p = new abc();
…return *p;
}
Утечка памяти!
Надо как-то так
abc f(){
… abc x;
…return x;
}
Язык С++ 35
Задачи на 14 апреля
Язык С++ 36
Задачи на 14 апреля1. Для string определить substr:
string substr(откуда, сколько)
string s = "abcdefg";string s1 = s.substr(2, 4); // "cdef"
2. Определить класс abc и в нем метод num(). Этот метод при вызове должен возвращать количество экземпляров abc, существующих в данный момент.
abc x; abc y; // 2 экземпляра{ abc z; // 3 экземпляра} // снова 2 экземпляра
Замечание: В задаче есть одна тонкость (простое решение в некоторых случая дает неправильный ответ..)
3. Напишите функцию atоi_oct, которая переводит строку, содержащую запись числа в восьмеричной системе счисления в число. Например:
int i = atoi_oct( "104"); // ответ д.б. 68
Пожалуйста, не пользуйтесь в этой задаче стандартными функциями.
4. Прочитать целые числа из файла и напечатать их в обратном порядке (с помощью list или vector)
Язык С++ 37