slide1 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Д.з. на 14 апреля PowerPoint Presentation
Download Presentation
Д.з. на 14 апреля

Loading in 2 Seconds...

play fullscreen
1 / 45

Д.з. на 14 апреля - PowerPoint PPT Presentation


  • 182 Views
  • Uploaded on

Д.з. на 14 апреля. Язык С++. 1. Задача 1: substr – с временным массивом. class string { ... string substr(int from, int len) const; // const !!  }; string string::substr(int from, int len) const { char* tmp = new char[len+1]; // Отводим временный массив символов.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Д.з. на 14 апреля' - dustin


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
1 substr
Задача 1: substr – с временным массивом

class string {

...

string substr(int from, int len) const;// const !! 

};

string string::substr(int from, int len) const

{

char* tmp = new char[len+1]; // Отводим временный массив символов.

for (int i=0; i<len; i++) // Копируем туда подстроку.

tmp[i] = str[i+from];

tmp[len] = '\0';

string res(tmp); // Создаем строку-результат

delete [] tmp; // Теперь tmp можно удалить

return res;

}

Язык С++

2

1 substr1
Задача 1: substr – с доп. конструктором

// Вспомогательный конструктор – создает строку данной длины

string::string(const char* s, int num) : len(num)

{

p = new char[num + 1];

for (int i = 0; i < num; i++)

p[i] = s[i];

p[num] = '\0';

}

// Теперь substr пишется _очень_ просто

string string::substr(int from, int num) const

{

return string(p + from, num);

}

Язык С++

3

itoa oct
itoa_oct

void itoa_oct(char* s, int n)

{

// Сначала ищем, где будет конец

// строки

char* p = s;

int n1 = n;

while (n1 > 0) {

p++; // В цикле делим на 8 и

n1 /= 8; // сдвигаем указатель.

}

*p = '\0'; // Сразу ставим '\0'

// на конце

// Пишем цифры в обратном

// порядке.

// Цикл похож напервый, но

// теперь еще пишем цифры.

n1 = n;

while (n1 > 0) {

p--;

*p = n1 % 8 + '0';

n1 /= 8;

}

}

// Пример вызова:

char s[20];

int i;

cin >> i;

itoa_oct(s, i);

cout << s;

Язык С++

5

5

itoa oct1
itoa_oct –вариантыинтерфейса
  • Результат – строка

string itoa_oct(int n)

{

char buff[20]; // Можно 12… заполняем buff,как напредыдущем слайде …

return string(buff);

}

// Пример вызова

cout << itoa_oct(i);

Можно сразу заполнять с конца, от buff+19 !

Язык С++

6

6

itoa oct2
itoa_oct –плохие вариантыинтерфейса

char* + динамическая память

char* itoa_oct(int n)

{

char* p = new char[…]; … заполняем …

return p;

}

cout << itoa_oct(i);

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

очень плохо: char* + локальная память

char* itoa_oct(int n)

{

char buff[20]; … заполняем …

return buff;

}

Указатель на несуществующую память!

Язык С++

7

slide8
class person_info {

public:

long phone; // Телефон

string address;// Адрес

person_info(long ph = 0,

const string& addr = "") :

phone(ph), address(addr)

{}// Лучше описать к-р

};// по умолчанию

// Телефонная книга

map<string, person_info> pb;

// Пример заполнения

pb["Иванов"] = person_info(

3223322, "Липовая ул. 1");

pb["Петров"] = person_info(

2991234, "Невский пр. 22");

// Пример использования

cout << pb["Иванов"].address

<< ", " << pb["Иванов"].phone;

// Или так более эффективно

p = pb.find("Иванов");

cout << p->second.address <<

", " << p->second.phone;

Телефонная книга
slide9
Задача 1: Частотный словарь

map<string, int> freq;

string s;

… открываем файл …

while (f >> s) {// Читаем слово

freq[s]++;// Увеличиваем счетчик (или можно find и insert)

}

// Печатаем ответ

map<string, int>::iterator p;

for (p = freq.begin(); p != freq.end(); p++) {

cout << p->first << " - " << p->second << "\n";

}

slide10
Задача 4: треугольники

void CTrianglesView::OnDraw(CDC* pDC)

{

// Начальные значения – примерно

// равносторонний преугольник

int x1=0, y1=0, x2=1000, y2=0,

x3=500, y3=866;

// Цикл "Пока не получится очень

// маленький треугольник"

while ((x1-x2)*(x1-x2)+

(y1-y2)*(y1-y2)>=2 ) {

// Рисуем треугольник

pDC->MoveTo(x1, y1);

pDC->LineTo(x2, y2);

pDC->LineTo(x3, y3);

pDC->LineTo(x1, y1);

// Пересчитываем

// координаты точек – теперь

// нам нужны середины сторон

int x1_ = (x2+x3)/2,

y1_ =(y2+y3)/2,

x2_ = (x1+x3)/2,

y2_ = (y1+y3)/2;

x3_ = (x1+x2)/2,

y3_ = (y1+y2)/2;

x1 = x1_; y1 = y1_;

x2 = x2_; y2 = y2_;

x3 = x3_; y3 = y3_;

}

}

Язык С++

10

10

5 sierpinski
Задача 5: Sierpinski

// Воспомогательная рекурсивная функция

void DrawSierpinski(CDC* pDC, int x1, int y1, int x2, int y2, int x3, int y3)

{

// Если треугольник очень маленький - ничего не делаем

if ( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)<=2 )

return;

// Рисуем треугольник

pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2);

pDC->LineTo(x3, y3); pDC->LineTo(x1, y1);

// Считаем середины

int x1_ = (x2+x3)/2, y1_ =(y2+y3)/2, x2_ = (x1+x3)/2,

y2_ = (y1+y3)/2, x3_ = (x1+x2)/2, y3_ = (y1+y2)/2;

// Вызываем функцию рекурсивно для трех маленьких треугольников

DrawSierpinski(pDC, x1, y1,x2_, y2_, x3_, y3_);

DrawSierpinski(pDC, x1_, y1_,x2_, y2_, x3, y3);

DrawSierpinski(pDC, x1_, y1_,x2, y2, x3_, y3_);

}

Язык С++

11

11

5 sierpinski1
Задача 5: Sierpinski - продолжение

Еще способ: с помощью случайной последовательности точек

Язык С++

12

1 strcpy
Задача 1: strcpy

// Через for

void strcpy(char* to, const char* from)

{

int i;

for (i=0; from[i]!='\0'; i++)

to[i] = from[i];

to[i] = '\0';

}

Замечание:На самом деле strcpy имеет тип char* и возвращает to,как результат. Но мы в примерах для краткости этого не делаем.

// С использованием указателей

// (и, для разнообразия, через

// while)

void strcpy(char* to, const char*from)

{

const char* p1= from;

char* p2 = to;

while (*p1 != '\0') {

*p2 = *p1;

p1++; p2++;

}

p2 = '\0';

}

Язык С++

14

1 strcpy1
Задача 1: strcpy - продолжение

// Самое короткое решение

void strcpy(char* to, const char* from)

{

while (*to++ = *from++);

}

Язык С++

15

2 reverse
Задача 2:reverse

void reverse (char* str)

{

char* p = str;

char* q = str + strlen(str) – 1;// Последний символ

for (;p < q; p++, q--) {

// Меняем местами

chartmp = *p;

*p = *q;

*q = tmp;

}

}

Язык С++

16

slide17

Еще про ассоциативные контейнеры

Язык С++

17

multiset multimap
multiset и multimap - обзор

#include <set>

multiset<int> s;

s.insert(6);

s.insert(2);

s.insert(9);

s.insert(6);

for(multiset<int>::iterator p =

s.begin(); p!=s.end(); p++)

cout << *p << " ";

// 2 6 6 9

#include <map>

multimap<double, int> m;

m.insert(make_pair(4.5, 2));

m.insert(make_pair(4.5, 8));

[] не работает

find возвращает первую пару

Язык С++

18

slide20
Пример
  • reverse(итератор начала, итератор конца);

#include <algorithm>

vector<int> v;

… Заполняем v …

reverse(v.begin(), v.end());

list<double> l;

… Заполняем l …

reverse(l.begin(), l.end());

string s = “abcdef”;

reverse(s.begin(), s.end());

Язык С++

20

slide21
Алгоритмы STL
  • #include <algorithm>
  • Весь интерфейс алгоритмов - через итераторы

Схема:

Контейнеры  Итераторы  Алгоритмы

"Алгоритмы и контейнеры хорошо работают вместе, потому что ничего не знают друг о друге"

Язык С++

21

slide22
Еще пример - sort

#include <algorithm>

vector<int> v;

… // Заполняем v

sort(v.begin(), v.end());

deque<double> d;

… // Заполняем d

sort(d.begin(), d.end());

  • Замечание: sort работает только для vector и deque

Язык С++

22

accumulate
Еще пример - accumulate
  • accumulate – найти сумму

#include <numeric>// Не в <algorihtm> !…

vector<int> v;

… Заполняем v …

int sum = accumulate(v.begin(), v.end(), 0); // Ищем сумму

Язык С++

23

slide24
Сложные (более-менее) алгоритмы

sort

binary_search

merge

max_element, min_elementmax_element(v.begin(), v.end());

возвращает итератор

random_shuffle

… и еще несколько…

Очень простые алгоритмы

accumulate

reverse

copy

find

fill – заполнить значением

… и еще много …

Еще некоторые возможности через несколько занятий

Подробнее об алгоритмах
slide26
Венгерская нотация

Charles Simonyi

iAbc – целая переменная

bAbc – логическая переменная

pAbc – указатель

sAbc - строка

CAbc – класс

m_iAbc – поле (целое)

m_pAbc – поле (указатель)

Язык С++

26

slide27
Классы в MFC можно разделить на такие группы:

Классы, которые используются непосредственно

CPoint – точка (x, y)

CRect – прямоугольник

CPen, CBrush, CFont – объекты для рисования (перо, кисть, шрифт)

Классы, которые используются, как базовые классыCWnd -окно

CView –окно приложения - определяем C…View - переопределям OnDraw

Некоторые классы используются и непосредственно, и как базовые

CButton – кнопка.

Язык С++

27

slide28
Файлы, из которых состоит MFC приложение
  • Остальные файлы, как правило, можно не смотреть.

Часто нужно менять классы:

CAbcView – окнодля вывода

CAbcApp – ‘приложение’ – действия при начале/конце работы, место для глобальных переменных и т.д.

CAbcDoc – будет позже..

Язык С++

28

windows1
Особенности рисования в Windows программах

OnDraw вызывается каждый раз, когда надо изобразить окно или часть окна

Следовательно:

Рисование должно делаться по возможности быстро

Желательно никаких операций ввода/вывода, сложных расчетов и т.д.

Еще следствия дальше…

Язык С++

29

circles
Пример – программа Circles

Картины из кружков.

Новые кружки появляются при щелчке мышью

Язык С++

30

slide31
Как что-то поменять в окне? Обработка событий.

Как добавить реакцию на событие (click)?

Добавляем фунцию – обработчик сообщения (инструкции на сайте). Появляется:

void CirclesView::OnLButtonDown(UINT nFlags, CPoint point)

{

… что надо делать при щелчке левой кнопкой …

}

Язык С++

31

slide32
Как что-то поменять в окне? Попытка 1 (наеправильная)

Что делать при обработке события, чтобы поменять картинку?

void CirclesView::OnLButtonDown(UINT nFlags, CPoint point){ …откуда то взяли pDC … pDC->Ellipse(point.x – 10, point.y – 10,// Рисуем кружок point.x + 10, point.y + 10); }

Плохо: картинка пропадет при перерисовке.

Язык С++

32

slide33
void OnDraw(CDC* pDC)

{

for (int i = 0; i < m_circles.size();

i++) {

pDC->Ellipse(m_circles[i].x – 10,

m_circles[i].y – 10,

m_circles[i].x + 10,

m_circles[i].y + 10);

}

OnLButtonDown: добавляем круг

m_circles.push_back(point);

Плохо: При щелчке ничего не будет изменяться.

Как что-то поменять в окне. Попытка 2 (почти правильная).
  • Мы должны всегда быть готовы перерисовать картинку
  • Значит, все данные об изображении должны храниться в памяти.
  • Храним информацию о картинке

в CCirclesView

class CCirclesView { …

vector<CPoint> m_circles;

  • Рисование очень простое

Язык С++

33

invalidate
Invalidate() – запрос на перерисовку окна.

OnLButtonDown: добавляем круг (Правильный вариант)

void CCirclesView::OnLButtonDown( UINT nFlags, CPoint point)

{

m_circles.push_back(point);

Invalidate();// Запрос на

} // перерисовку

Схема обработки сообщения: При обработке сообщения, как правило, надо:

Поменять информацию о картинке

Сообщить системе, что надо перерисовать картинку (Invalidate())

Замечания:

Изображение моргает… InvalidateRect и т.д.

Обычно пишут сложнее – на следующем занятии (Document/View)

Invalidate. Как что-то поменять в окне. Теперь правильно (хотя можно и улучшить)

Язык С++

34

slide36
Зачем нужны шаблоны?

int max(int x, int y)

{

if (x < y)

return y;

else

return x;

}

... тоже для double ...

... тоже для short  ...

... тоже для time   ...

и т.д.

template <class T> Т max(T x, T y)

{

if (x < y)

return y;

else

return x;

}

// Пример вызова

int i, j, k;

...

k = max(i, j);

Генерируется:

int max(int x, int y){ if (x<y) …}

Язык С++

36

slide37
Синтаксис шаблоновфункций, замечания

double x, y, z;

...

z = max(x, y);

Генерируется:

double max(double x, double y)

{ if (x<y) …}

Синтаксис

template <параметры>

<описание функции>

Замечания:

Параметров м.б. несколько:

template <class T1, class T2>

void copy(T1* to, T2* from, int n)

{

for(int i = 0; i < n; i++)

to[i] = from[i];

}

double a[100]; int b[100];

copy(a, b, 100);

typename T

- то же, что class T

Язык С++

37

instantiation
Генерация шаблона (instantiation)

Параметры шаблона должны выводиться из параметров вызова функции

int i,j;

max(i, j)

 T == int

М.б. не напрямую, через указатели, ссылки и т.д.

double a[100]; int b[100];

copy(a, b, 100);

 T1 = double, T2 = int

Так будет ошибка:

template <class T>

void f(int i)// T нет в параметрах{ T x;

}

f(5); // Could not deduce..

// Не вывести тип T

Можно явно задавать параметр

f<double>(5); // OK

Для функций - редко.

Язык С++

38

slide39
Порядок подбора функции

double x; inti;

max(x, i);

// Ошибка

Порядок подбора функции

Обычная функция, без преобразований

Шаблон, без преобразований

Обычная функция, с преобразованиями

Никогда: шаблон с преобразованиями!

Что же делать?

max(x, (double)i)

max<double>(x, i)

Язык С++

39

slide40
Что будет, если тип "не подходит" шаблону?

complex c1, c2;

max(c1, c2)

// Ошибка: оператор< не определен

Диагностика м.б. не очень понятная

concepts в C++ 0x

time t1, t2;

max(t1, t2)

ОК, если задать оператор <

Язык С++

40

slide41
Перегрузка шаблона функции.

char s1[] = "abc";

char s2[] = "klm";

cout << max(s1, s2);

// Не то сравнение!

Специализация

char* max(char* x, char* y)

{

if (strcmp(x,y) <0)

return x;

else

return y;

}

Тут было обсуждение того, почему такое определение max для char плохо с точки зрения поддержки константности (константных строк и т.д.), и как это можно исправить.

Язык С++

41

slide42
Замечания

Может увеличится размер программы (code bloat)

Обычно часто используете и редко пишете свои шаблоны.

Язык С++

42

slide44
Задачи на 28 апреля

Для программы Circles реализовать удаление кружков (например, правой кнопкой)

* Для программы Circles реализовать перетаскивание кружков с места на место.

Шаблон функции swp, которая меняет местами два объекта одного типа.double x = 1.1, y = 2.2;swp(x, y);cout << x << y; // 2.2 1.1(Замечание: вообще-то лучше бы назвать ее swap, но такая функция уже есть стандартная).

* Специализация swp для mystring (т.е. того string, который мы писали).string s1 = "abc";strings2 = "klm";swp(s1, s2);// klm abcПояснение: swp из пункта 3 будет, скорее всего, работать и для строк. Зачем же его тогда специализировать? Дело в том, что можно написать специализацию, которая работает гораздо быстрее(Подсказка: просто поменять местами отдельно указатели и отдельно длины).

Язык С++

44

slide45
Задачи на 28апреля

Еще подсказка: если хотите, для простоты можете объявить все поля string как public. Это немного упростит задачу.

Опишите функцию, которая для данного вектора целых чисел ищет сумму всех его элементов, кроме максимального и минимального.(Будем для простоты считать, что и максимальный и минимальный встречаются в векторе только один раз).

Если получится, пожалуйста, решите эту задачу используя стандартные алгоритмы.(Т.е. желательно самим никаких циклов не писать)

Язык С++

45