Про экзамен

37
Про экзамен

Upload: machiko-rin

Post on 02-Jan-2016

45 views

Category:

Documents


2 download

DESCRIPTION

Про экзамен. Про экзамен – как он будет проходить, льготы за баллы и т.д. 10 задач / вопросов Письменно, 90 мин. Проверю примерно через 30- 6 0 мин, в зависимости от количества участников Если оценка не очевидна, или если в ответах что-то непонятно , то потом еще м.б. устные вопросы - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Про экзамен

Про экзамен

Page 2: Про экзамен

Про экзамен – как он будет проходить, льготы за баллы и т.д. 10 задач / вопросов

Письменно, 90 мин. Проверю примерно через 30-60 мин, в зависимости от

количества участников Если оценка не очевидна, или если в ответах что-то

непонятно, то потом еще м.б. устные вопросы Баллы льготы

16 допуск 24 -1 задача/вопрос 32 -2 40 -3 48 -3 + можно пользоваться любыми материалами 56 -4 + можно пользоваться любыми материалами 64 -5 + можно пользоваться любыми материалами

Page 3: Про экзамен

Про экзамен – сроки, место 22 мая – 10:00

Сбор у баобаба. Для тех, кто придет позже – будет объявление на расписании 3 курса

26 мая – 5 параСбор в 2410. Поскольку время будет ограничено – только по предварительной записи, не больше 10 чел. Заявки принимаются до 24 мая включительно.

Если будут желающие – можно 28 мая на 4 паре или 29 мая на 1 паре. Если кто-то хочет сдавать в один из этих дней – пишите

И еще будет одна попытка во второй половине июня, точная дата будет известна позже

Page 4: Про экзамен

Задачи на 5 мая

Язык С++ 4

Page 5: Про экзамен

Шаблон для очередиtemplate <class T, int maxsize=100>class fixed_queue {

T s[maxsize];int first; // Номер первого эл-таint last; // Номер последн. эл-таint size; // Количество эл-тов

public: fixed_ queue(): first(0), last(maxsize-1), size(0){}

void push(const T& x){ if ( size == maxsize )

throw "overflow"; size++; last = (last + 1) % maxsize; s[last] = x;}

T pop(){ if ( size == 0 )

throw "empty"; size--; int old_first = first; first = (first + 1) % maxsize; return s[old_first];}

};

// Пример вызова:queue<int> q;q.push(11);q.push(22);cout << q.pop();

Page 6: Про экзамен

Совершенное числоperfect.hbool isPerfect(int n);

perfect.cppbool isPerfect(int n){

int sq_root = (int)sqrt((double)n);int sum = 1;

for (int i = 2; i<sq_root; i++) { if (n%i == 0)

sum += i + n/i;}

if (n % sq_root ==0) sum += sq_root;

return n == sum;}

// Самый эффективный вариантbool isPerfect(int n){

return n == 6 || n == 28 || n == 496 || n == 8128 || n == 33550336;

}

Page 7: Про экзамен

Еще вариант// Еще вариант…

namespace {const int perfects [] = { 6, 28, 496, 8128, 33550336 };}

bool isPerfect(int n){ return find(perfects, perfects + 5, n) != perfects +5;}

Или можно описать perfects, как локальную статическую переменную

Язык С++ 7

Page 8: Про экзамен

shared_stringclass shared_string {

char* p;// len для краткости не используем

// Воспомогaтельные методы

// Поставить указатель p на// данную строку и увеличить// в ней счетчик.void set_ptr(char * newp){

p = newp;(*newp)++;

}

// Уменьшить счетчик в строке, // на которую указывает p. // Если надо, удалить строку. void drop_ptr() {

(*p)--; if (*p == 0) { cout << "Deleting " << p + 1; delete [] p; }

}

public:

Язык С++ 8

Page 9: Про экзамен

shared_string - продолжениеshared_string(const char* s = ""){ p = new char[strlen(s)+2]; *p = 1; strcpy(p + 1, s);}

~shared_string(){ drop_ptr();}

shared_string(const shared_string& from){ set_ptr(from.p);}

shared_string& operator= (const shared_string& from) { if (p != from.p) { drop_ptr(); set_ptr(from.p); } return *this; }

void print() const { cout << p+1; }

}; // Конец определения класса

Язык С++ 9

Page 10: Про экзамен

Задачи на 12 мая

Язык С++ 10

Page 11: Про экзамен

Интегралdouble integral(

double (*f)(double), double a, double b)

{// Метод трапецийdouble h = (b-a)/100; // Шаг

double sum = (f(a)+f(b))*h/2;

for (double x=a+h; x<b;x+=h) {sum += f(x)*h;

}

return sum;}

// Пример вызова:double cube(double x){

return x*x*x;}

...cout << integral(cube, 0, 3);

Page 12: Про экзамен

Сортировка с помощью sort#include <algorithm>…

int sumdig(int n){

int sum = 0;while(n != 0) {

sum += n % 10;n /= 10;

}return sum;

}

bool cmp_sumdig(int i, int j){

return sumdig(i) < sumdig(j);}

// Пример использованияvector<int> v; …sort(v.begin(), v.end(), cmp_sumdig);

Page 13: Про экзамен

Сортировка с помощью multimap#include <map>…multimap<int, int> m;

vector<int>::iterator q;for (p = v.begin(); p != v.end(); p++) {

m.insert(make_pair(sumdig(*p), *p)); // Заносим в m пары } // сумма цифр число

multimap<int, int>::iterator q;for (q = m.begin(); q != m.end(); q++) { // Печатаем числа в

cout << q->second << " "; // порядке возрастания} // ключей

Page 14: Про экзамен

numeric_limits template <class T>class numeric_limits {public:

static T max();// Достаточно объявления.// Описание можно не задавать,// все равно оно не потребуется

};

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

inline int numeric_limits<int>::max(){

return 0x7FFFFFFF;}

inline unsignednumeric_limits<unsigned>::max()

{return 0xFFFFFFFF;

}

inline shortnumeric_limits<short>::max()

{return 0x7FFF;

}

… и т.д. …

// Примеры использованияcout << numeric_limits<int>::max();cout << numeric_limits<unsigned>::max();cout << numeric_limits<short>::max();

Page 15: Про экзамен

Прием «Trait» – класс свойствВ numeric_limits задается, в некотором смысле, функция – с типом

связывается число int 0x7FFFFFFF unsigned 0xFFFFFFFF … и т.д. …

Прием: если надо с классами связать значения (числа, другие типы и т.д.), это удобно делать примерно как в numeric_limits

Общий шаблон + специализации Связываемое значение задается, как статическая функция

или константа (если это число), или как typedef (если это тип)

Такой прием называется trait (класс свойств)

Основной прием при программировании шаблонов... (Если у вас непонятная проблема с шаблонами – попробуйте

traits…)

Page 16: Про экзамен

Препроцессор

Язык С++ 16

Page 17: Про экзамен

#define #define ABC 123

Заменить всюду в тексте ABC на 123

Может быть с параметрами#define SQR(x) x * x Заменить всюду в тексте SQR(что-то) на что-то * что-тоНапример: SQR(a[i]) a[i] * a[i]

Может быть без правой части

#define ABC(x)

Всюду заменить ABC(что-то) на пустую строку (т.е. выкинуть).

Page 18: Про экзамен

Опасности (почему #define хуже inline функции)#define SQR(x) x*x

Проблема: приоритет операций

SQR(x+1) x+1 * x +1

Решение: Взять все в скобки И аргументы взять в скобки

#define SQR(x) ((x)*(x))

Еще проблема:SQR(i++)

Page 19: Про экзамен

Где не надо использовать #define Вместо const

#define SIZE 100

const int size = 100; (или enum)

Вместо inline или template#define SQR(x) x*x

template <class T>inline T sqr(T x){ return x*x;}

Page 20: Про экзамен

Когда имеет смысл использовать #define?1. Если хотим быстро и

эффективно добавлять / убирать какой-то код (для отладки)

#define TRACE(x) cout << (x)

TRACE(a[i]); cout << (a[i]);

Когда отладим, просто напишем:

#define TRACE(x)

и все отладочные печати вообще исчезнут из кода

2. Если то, что мы хотим записать в define – не функции.

Для любителей Pascal:

#define BEGIN {#define END }

Page 21: Про экзамен

Когда имеет смысл использовать #define? Примерint numeric_limits<int>::max(){

return 0x7FFFFFFF;}

unsignednumeric_limits<unsigned>::max()

{return 0xFFFFFFFF;

}

… и еще несколько очень похожих определений…

// Вариант с препроцессором#define NUMLIM(type, val) \template<> type \

numeric_limits<type>::max() \{ \

return val; \}

// Теперь несколько очень похожих// определений записываются// совсем коротко

NUMLIM(int, 0x7FFFFFFF)NUMLIM(unsigned, 0xFFFFFFFF)

… и еще несколько вызовов NUMLIM …

Page 22: Про экзамен

Оператор # # x - stringize

Взять x в кавычки.

#define ABC(x) #x

ABC(test) "test"

Удобно в отладочных макро:

#define TRACE(x) cout << #x " = " << (x)

TRACE( 2*a[i+j] ) cout << "2*a[i+j]" " = " << (2*a[i+j])

Напоминание: две строчки подряд – склеиваются

Page 23: Про экзамен

Оператор ## ## - склейка

a ## x – записать a и значение x подряд, без пробела.

#define ABC(x) a ## x ## b

ABC(test) atestb

Пример (не убедительный…):

#define MYDEFS(x) \int i##x; \string s##x; \double dbl##x; \

MYDEFS(Test) int iTest; string sTest; double dblTest;

Page 24: Про экзамен

#if #if

#if условие … какие-то строки …

#endif

Включать <какие-то строки> если выполняется условие

Условие – константы, препроцессорные переменные (из #define), арифметические и логические операции

#define ABC 1…

#if ABC *3 < 100…

#endif

М.б. #else и #elif

#if ABC == 1…

#elif ABC == 2…

#else…

#endif

Page 25: Про экзамен

#ifdef, #ifndef #ifdef ABC

Если ABC определено в #define (все равно как)

#ifndef ABC

Если ABC не определено в #define

Page 26: Про экзамен

Примеры использования - 11. Для разных процессоров /

оперционных систем

#if OS == 1… код для Windows

#elif OS == 2 … код для Unix#elif OS == 3 … код для Apple#else … код для Simbian#endif

2. Для отладки

#if DEBUG cout << a[i] << b[k]; …#endif

или еще лучше

#if DEBUG#define TRACE(x) cout << (x)

#else#define TRACE(x)

#endif

Page 27: Про экзамен

Примеры использования - 23. Чтобы закомментировать

большой кусок

#if 0… большой кусок кода …

#endif

4. Чтобы включить #include один раз

--- abc.h ------------------------void f(int i);extern int k;class abc { … };-----------------------------------

#include "abc.h"…#include "abc.h" Ошибка – повторное

объявление

А так все будет нормально:--- abc.h ------------------------------#ifndef ABC #define ABC

void f(int i); extern int k; class abc { … };#endif---------------------------------------- Можно еще написать

#pragma once

Page 28: Про экзамен

RTTI (динамическая идентификация

типа)

Язык С++ 28

Page 29: Про экзамен

typeidПусть у нас иерархия классов: shape

circle square rhomb

shape* p; // Указывает на // какую-то фигуру

Вообще-то компьютер знает, на какую фигуру указывает p (за счет таблицы виртуальных функций)

И мы можем узнать!

Page 30: Про экзамен

typeid typeid – оператор, параметром м.б. выражение или тип

(примерно как у sizeof)

if (typeid(*p) == typeid(square))

Тип результата: класс type_info В основном для того, чтобы сравнивать между собой Метод name() – имя класса

Имеет смысл, если есть виртуальные функции Если нет виртуальных функций – не ошибка, но нет смысла

Должна быть включена опция “Enable Runtime Type Info”

Вообще-то лучше не использовать..

Page 31: Про экзамен

Объекты - функции (функторы)

Язык С++ 31

Page 32: Про экзамен

Функторы (объекты – функции) Для классов можно переопределять operator()// Довольно бессмысленный пример..class abc {

int operator () (int i){ return i*i;}

};

abc x; // x ведет себя, как функция возведения в квадрат

x(n) x.operator()(n); n*n

Такие объекты, называют функторами или обьектами- функциями.

Язык С++ 32

Page 33: Про экзамен

Функторы для сортировкиclass my_sorter {public:

bool operator () (int i, int j){ return i % 100 < j % 100;}

};

my_sorter x;

x ведет себя, как функция сортировки с прошлого занятия

if (x(i, j)) …

sort(v.begin(), v.end(), x); // Работает!

А если мы хотим сортировать по последним n цифрам ?!

Идея – добавить в my_sorter поле и конструктор!

my_sorter x(n);// Сортирует по n цифрам

sort(v.begin(), v.end(), x); // Или можно так:

sort(v.begin(), v.end(), my_sorter(n));// Создается временный// обьект my_sorter

Язык С++ 33

Page 34: Про экзамен

Задачи на 19 мая

Язык С++ 34

Page 35: Про экзамен

Задачи на 19 мая - 11. Написать макро ASSERT(условие).

Во время выполнения, если условие не выполняется, должно быть напечатано что-то вроде: "Сondition <текст условия> failed“.

Если условие выполняется, ничего не должно печататься. И все это должно быть определено с помощью #define, чтобы потом весь

генерируемый в ASSERT код легко можно было убрать.

Пример использования:ASSERT(a[i] > 0)

Если действительно a[i] больше 0 - ничего не происходит, иначе печатается сообщение об ошибке

Подсказка: схема решения какая-то такая:

#define ASSERT(…) \ if (…) cout << …

(где вместо многоточий вам надо что-то вписать).

Продолжение на следующем слайдеЯзык С++ 35

Page 36: Про экзамен

Задачи на 19 мая - 22. Таблица ошибок

Пусть у меня в программе есть таблица сообщений об ошибках с номерами ошибок. Например:

map<int, string> errors;errors[1] = “Какая-то проблема";errors[2] = “Все плохо..";errors[3] = “У вас все неправильно";

… и еще много ошибок …

Написать макро, чтобы этот код выглядел так:

ERROR_TABLEERROR(1, “Какая-то проблема“)ERROR(2, “Все плохо..“)ERROR(3, “У вас все неправильно“)

… и еще много ошибок …

Т.е. надо написать определения ERROR_TABLE и ERROR такие, чтобы ERROR_TABLE превращалось в map<int, string> errors;, ERROR(1, “Какая-то проблема“) превращалось в errors[1] = “Какая-то проблема"; и т.д.

Продолжение на следующем слайде

Язык С++ 36

Page 37: Про экзамен

Задачи на 19 мая – 2 3. Дан вектор CShape*. Сколько среди этих фигур квадратов?

4. Написать my_sorter, который позволяет сортировать по последним n цифрам (см. последний слайд перед задачами)

5. Написать шаблон sumpos с одного из предыдущих занятий так, чтобы тип результата определялся таким правилом:

Если T::value_type – целое число любого типа (int, long, short), то результат sumpos д.б. long

Если T::value_type – вещественное число любого типа (float, double) – то результат sumpos д.б. double

Подсказка 1: Я бы советовал описать trait, который всем целым типам ставит в соответствие long, а всем вещественным – double

Подсказка 2: Это, видимо, должно быть что-то похожее на numeric_limits, но внутри - typedef

Язык С++ 37