37
Д.з. на 31 марта Язык С++ 1

Д.з. на 31 марта

  • 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

Page 1: Д.з. на  31  марта

Д.з. на 31 марта

Язык С++ 1

Page 2: Д.з. на  31  марта

Задача 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);}

Page 3: Д.з. на  31  марта

Задача 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

Page 4: Д.з. на  31  марта

Задача 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; // Раз мы здесь, то строки не равны}

Page 5: Д.з. на  31  марта

Задача 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;} // Если стек пуст, об // этом никак не

сообщается

Page 6: Д.з. на  31  марта

Задача 3: еще вариант// Вариант 2:void f(stack& s){ int* p = new int[1000]; … что-то делаем с p … try { cout << s.pop(); } catch (…) { delete [] p; throw; } delete [] p;} // Слишком сложно? // Использовать RAII?

Page 7: Д.з. на  31  марта

Задача 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();}

Page 8: Д.з. на  31  марта

RAIIResource Acquisition Is InitializationПолучение ресурса есть инициализация

Пусть обязательно надо выполнить какое-то действие в конце функции

(удалить память, закрыть файл, восстановить форму курсора и т.д.)

Совет: • завести вспомогательный класс• выполнять это действие в деструкторе

Преимущества:• Получается короче• thread safe – действие будет выполнено даже при наличии

исключений

• Замечание: Если действие – это ‘освободить память’ то можно использовать стандартные классы (vector) или классы boost (scoped_ptr, shared_ptr)

Page 9: Д.з. на  31  марта

Д.з. на 7 апреля

Язык С++ 9

Page 10: Д.з. на  31  марта

Задача 3: += для строкПлан действий:1. Отвести новый кусок памяти под длинную строку2. Скопировать туда первую строку3. Дописать вторую строку4. Удалить старый кусок памяти5. Установить новые p и len

Язык С++ 10

Page 11: Д.з. на  31  марта

Задача 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

Page 12: Д.з. на  31  марта

Доп.задачи про списки

Язык С++ 12

Page 13: Д.з. на  31  марта

Задача 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

Page 14: Д.з. на  31  марта

Замечания про operator= и конструктор копирования

25.03.2008 Язык С++ 14

Page 15: Д.з. на  31  марта

Замечания про оператор = и конструктор копирования class abc {

string a, b, c;};

Тут оператор = и конструктор копирования по умолчанию работают правильно. a = from.a; b = from.b; c = from.c;(Вызываются переопределенные операторы =)

Значит, тут оператор = и конструктор копирования лучше не переопределять.

Язык С++ 15

Page 16: Д.з. на  31  марта

Локальные, глобальные и статические переменные

Язык С++ 16

Page 17: Д.з. на  31  марта

Какие бывают переменные? Локальная

Внутри функции

void f(){ int a = 56;

ГлобальнаяВне функции

int a = 56;void f(){ …

СтатическаяВнутри функции, static

void f(){ static int a = 56;

Тут на доске была нарисована таблица: для каждого из этих видов переменных – когда они создаются, когда уничтожаются и из какой части программы они видны.

static переменные – это, в каком-то смысле, среднее между локальными и глобальными

Page 18: Д.з. на  31  марта

Примерint f(){ static int i = 0; i++; return i;}

Язык С++ 18

Page 19: Д.з. на  31  марта

Статические поля и методы

Язык С++ 19

Page 20: Д.з. на  31  марта

static методыclass abc {

static void f(int i); …

}

void abc::f(int i){ …}

// Вызовabc::f(56);

Обычные функции(только описанные как бы внутри класса)

Не могут использовать поля класса

Точнее, могут использовать только статические поля

Конечно, не могут быть virtual Могут быть private и protected В методах класса можно писать

просто f(i);

Зачем? По смыслу очень тесно

связанные с классом Вспомогательные (private)Язык С++ 20

Page 21: Д.з. на  31  марта

static методы - пример// Current time возвращает // текущее время

class time {…

static time current() { … }};

time t = time::current();

Язык С++ 21

Page 22: Д.з. на  31  марта

static поляclass abc {

static int i; …

}

int abc::i = 0;

// Использование аbc::i = 5;

Обычные глобальные переменные(только описанные как бы внутри класса)

Могут быть private и protected В методах класса можно писать

просто i

Не забывайте объявление int abc::i = 0;

Зачем? По смыслу очень тесно

связанные с классом Вспомогательные (private)

Язык С++ 22

Page 23: Д.з. на  31  марта

static поля - замечания static const целые можно описывать прямо в классе

class abc {static const int maxsize = 100;…

};

На старых компиляторах это не работает

Можно понимать static поля, как поля, общие для всех членов класса

Язык С++ 23

Page 24: Д.з. на  31  марта

Что еще может быть в классе, кроме полей и

методов

Язык С++ 24

Page 25: Д.з. на  31  марта

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

Page 26: Д.з. на  31  марта

typedef в классе

class abc { typedef long* myptr;

…};

// Использованиеabc::myptr x; // Вне классаmyptr x; // В классе

М.б. private/protected

Язык С++ 26

Page 27: Д.з. на  31  марта

Вложенные классы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

Page 28: Д.з. на  31  марта

Вложенные классы и права доступа (дружба) Стандарт: не друзья

Новый стандарт:внутренние классы могут использовать private поля внешнего класса.

Page 29: Д.з. на  31  марта

STL – Standard Template Library

Язык С++ 29

Page 30: Д.з. на  31  марта

Alexander Stepanov

Page 31: Д.з. на  31  марта

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

Page 32: Д.з. на  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

Page 33: Д.з. на  31  марта

Итераторы

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

Page 34: Д.з. на  31  марта

Еще про тип char char - это маленькое число

unsigned char 0 – 255 signed char -128 – 127 char зависит от компилятора

Все арифметическиe операции работают

if (c > '0' && c <= '9')

int i = c – '0'; // Переводим символ от ‘0’ до ‘9’ // в соответствующее число

Язык С++ 34

Page 35: Д.з. на  31  марта

Замечание про то, как вернуть объект из функцииabc f(){

… abc* p = new abc();

…return *p;

}

Утечка памяти!

Надо как-то так

abc f(){

… abc x;

…return x;

}

Язык С++ 35

Page 36: Д.з. на  31  марта

Задачи на 14 апреля

Язык С++ 36

Page 37: Д.з. на  31  марта

Задачи на 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