<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://mit.spbau.ru/sewiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alexey.Gurevich</id>
		<title>SEWiki - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://mit.spbau.ru/sewiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alexey.Gurevich"/>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Alexey.Gurevich"/>
		<updated>2026-04-07T23:22:39Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Alexey.Gurevich&amp;diff=384</id>
		<title>Участник:Alexey.Gurevich</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Alexey.Gurevich&amp;diff=384"/>
				<updated>2011-09-18T18:38:34Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Алексей Гуревич ==&lt;br /&gt;
[mailto:alexeigurevich@gmail.com alexeigurevich@gmail.com]&lt;br /&gt;
&lt;br /&gt;
[[Файл:Gurevich.JPG|200px|right]]&lt;br /&gt;
&lt;br /&gt;
''Образование''&lt;br /&gt;
&lt;br /&gt;
* 2010-наст.вр. Санкт-Петербургский академический университет РАН (магистратура)&lt;br /&gt;
* 2006-2010 Санкт-Петербургский государственный политехнический университет, Факультет технической кибренетики, кафедра Информационных и управляющих Систем (бакалавриат)&lt;br /&gt;
* 2002-2006 Лицей &amp;quot;Физико-техническая школа&amp;quot; Академического университета РАН&lt;br /&gt;
&lt;br /&gt;
''Опыт работы''&lt;br /&gt;
&lt;br /&gt;
* 07/2011-наст.вр. [http://bioinf.spbau.ru/ Лаборатория алгоритмической биологии], intern&lt;br /&gt;
* 03/2009-07/2010 СПбГПУ, каф. ИУС, researcher (Java)&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%98%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=350</id>
		<title>Исключения</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%98%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=350"/>
				<updated>2011-06-01T07:51:57Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: /* Исключения */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Обработка ошибок ==&lt;br /&gt;
В программах всегда возникают ошибки. Их надо уметь обрабатывать, иначе часто мы будем беспокоить пользователя по пустяку. Рассмотрим основные способы обработки ошибок.&lt;br /&gt;
&lt;br /&gt;
== Обработка кода возврата ==&lt;br /&gt;
Из каждой функции возвращаем код, в котором содержится дополнительная информация о результате работы функции. &lt;br /&gt;
Программист функции задает семантику этого кода. Одним из его значений должен быть &amp;quot;успех&amp;quot;. Результат функции возвращается через параметр, передаваемый по ссылке. &lt;br /&gt;
Такой подход увеличивает колличество кода. Нужно проверять код возврата. В зависимости от проекта, этот код может понадобиться проверять каждый раз после вызова функции.&lt;br /&gt;
Также пользователь функции должен знать семантику кода возврата. Для кода возврата можно не создавать отдельную переменную в сигнатуре функции.&lt;br /&gt;
Можно возвращать значение, которое не входит в множество допустимых значений. Например, результат функции всегда положительный, но мы возвратим отрицательное число, если что-то пошло не так.&lt;br /&gt;
Тогда вызов будет короче, но мы совместим ответственности - результат будет отвечает и за ошибки. Если множество значений функции в перспективе может расшириться, то этот способ не подходит.&lt;br /&gt;
&lt;br /&gt;
== Глобальная переменная errno ==&lt;br /&gt;
Все функции в случае возникновения ошибки записывают ее код в глобальную переменную errno. Проверять errno может понадобиться после каждого вызова.&lt;br /&gt;
При таком подходе мы можем строить выражения из вызовов функций. Использование глобальной переменной требует синхронизации в многопоточных приложениях.&lt;br /&gt;
&lt;br /&gt;
== SEH, Signals ==&lt;br /&gt;
Платформенно зависимые исключения и сигналы от ОС. Например деление на 0, извлечение квадратного корня из отрицательного числа, разъименование нулевого указателя, порча стека и т.п.&lt;br /&gt;
Обычно говорят о том, что дальнейшее выполнение программы не имеет смысла, потому часто явно не обрабатываются в программах. 24/7/365 сервисы обычно требуют обработки таких исключений.&lt;br /&gt;
Это отдельная большая тема.&lt;br /&gt;
&lt;br /&gt;
== Assert ==&lt;br /&gt;
Это утверждения, логические условия, истинность которых проверяется либо во время выполнения, либо во время компиляции (static assert). &lt;br /&gt;
Если статическое утверждение во время компиляции ложно, то возникает ошибка компиляции. Если во время вполнения утверждение ложно, то&lt;br /&gt;
в стандартный поток ошибок выводится текст этого утверждения и программа завершается. &lt;br /&gt;
Assert'ы отключаются, если при компиляции определен символ NDEBUG.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;cassert&amp;gt;&lt;br /&gt;
assert(1 + 1 == 2 &amp;amp;&amp;amp; &amp;quot;working with field which charcteristic &amp;gt; 2&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Строка с комментарием к assert'у &amp;quot;working with ...&amp;quot; - это ненулевой char const *, потому он всегда True и не влияет на результат логического И.&lt;br /&gt;
&lt;br /&gt;
== Исключения ==&lt;br /&gt;
Исключение - событие, возникающее во время выполнения программы. Обычно обозначает что-то негативное. Существуют различные точки зрения на то, когда нужно использовать исключения.&lt;br /&gt;
Некоторые используют их, когда произошло малейшее нарушение работы программы (например ошибка конвертации строки в число), а другие только в случае если дальнейшее выполнение программы не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Работа с исключениями состоит из следующих этапов:&lt;br /&gt;
* Выполнено условие, при котором стоит сообщить внешнему коду о произошедшей ошибке.&lt;br /&gt;
* Бросается исключение.&lt;br /&gt;
* Исключение всплывает по стеку вызовов программы до первой точки, в которой это исключение может быть обработано.&lt;br /&gt;
* В обработчике исключения можно выполнить все действия для восстановления программы и продолжить ее выполнение или если это не возможно в данном месте кода, бросить новое исключение дальше по стеку. &lt;br /&gt;
* Если исключение не было обработано и всплыло выше функции main, то вызывается обработчик unexpected, который по умолчанию завершает выполнение программы.&lt;br /&gt;
&lt;br /&gt;
Некоторые моменты: &lt;br /&gt;
* Если исключение поймано (обработано), то вызовутся деструкторы всех объектов, которые лежали на стеке от места бросания до места обработки.&lt;br /&gt;
* Если мы выделим память в куче, а затем кинем исключение, то выделенная память не будет освобождена (деструктор указателя ничего не делает).&lt;br /&gt;
* Реальный механизм работы исключений и его накладные расходы зависит от разрядности процессора и ОС.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим базовый синтаксис работы с исключениям ив C++:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
	try&lt;br /&gt;
	{&lt;br /&gt;
		if (a == 0)&lt;br /&gt;
			throw 0;&lt;br /&gt;
		int res = 10/a;&lt;br /&gt;
	}&lt;br /&gt;
	catch(int ex)&lt;br /&gt;
	{&lt;br /&gt;
		if (ex == 0)&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;division by zero&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	catch(float ex)&lt;br /&gt;
	{&lt;br /&gt;
		if (ex &amp;gt;= 0)&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;float&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Оператор &amp;lt;code&amp;gt;try {}&amp;lt;/code&amp;gt; показывает границы блока кода, в котором мы хотим ловить исключения. Исключения будут ловиться не только в самом блоке, &lt;br /&gt;
но и ниже по стеку вызовов - во всех функциях, вызванных из блока &amp;lt;code&amp;gt;try&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Оператор &amp;lt;code&amp;gt;catch(...){}&amp;lt;/code&amp;gt; определяет код-обработчик исключения, который выполняется в случае если оно было кинуто в &amp;lt;code&amp;gt;try&amp;lt;/code&amp;gt;. Аргумент &amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt; означает что будут ловиться все исключения.&lt;br /&gt;
Если мы хотим перехватить исключение какого-то конкретного типа, то в аргументе &amp;lt;code&amp;gt;catch&amp;lt;/code&amp;gt; объявляют переменную этого типа. Для классов и структур используется константная ссылка.&lt;br /&gt;
* Оператор &amp;lt;code&amp;gt;throw&amp;lt;/code&amp;gt; принимает экземпляр типа, который мы хотим кинуть.&lt;br /&gt;
&lt;br /&gt;
Давайте поймем почему код, который бросает примитивные типы плох?&lt;br /&gt;
В обработчике &amp;lt;code&amp;gt;catch&amp;lt;/code&amp;gt; нам приходится проверять какое целое значение было кинуто, чтобы понять что с ним делать.&lt;br /&gt;
Мы можем определить отдельный класс для каждого исключения и бросать уже объекты этих классов. &lt;br /&gt;
Это избавит нас от необходимости проверять еще какую-то информацию, неявно передаваемую в кидаемом экземпляре примитивного типа.&lt;br /&gt;
Для удобства в стандартной библиотеки &amp;lt;code&amp;gt;stl&amp;lt;/code&amp;gt; уже есть класс исключений &amp;lt;code&amp;gt;std::exception&amp;lt;/code&amp;gt;, объявленный в файле &amp;lt;code&amp;gt;&amp;lt;exception&amp;gt;&amp;lt;/code&amp;gt;. Для поддержания единообразности кода на C++, следует наследовать свои классы исключений от него. Также у &amp;lt;code&amp;gt;std::exception&amp;lt;/code&amp;gt; есть виртуальный метод &amp;lt;code&amp;gt;what()&amp;lt;/code&amp;gt;, который удобно использовать для возвращения информации об исключении&lt;br /&gt;
в удобном для прочитывания человеком формате. Также стандартная библиотека определяет некоторые другие классы, например &amp;lt;code&amp;gt;std::logic_error, std::runtime_error, std::bad_alloc&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Нужно помнить, что при выборе блока &amp;lt;code&amp;gt;catch&amp;lt;/code&amp;gt;, который соответствует кинутому исключению, приведение типов не происходит. Одновременно может быть активно только одно исключение, поэтому если во время всплытия исключения по стеку&lt;br /&gt;
до того как исключение найдет свой обработчик, кинется еще одно исключение, программа полностью закончит свое выполнение. Теперь давайте вспомним какой код выподняется &lt;br /&gt;
во время всплытия исключения - происходят вызовы всех деструкторов. Если хотябы один деструктор кинет исключение, то программа полностью завершится. Поэтому деструкторы не должны кидать исключений. &lt;br /&gt;
Теперь представим себе что будет, если кинуть исключение в конструкторе - до завершения конструктора объект не считается созданным, потому в случае падения исключения в конструкторе, деструктор создаваемого объекта &lt;br /&gt;
не будет вызван. То есть если мы уже выделили какой-то ресурс в конструкторе, а потом в нем возникло исключение, то ресурс не будут освобожден.&lt;br /&gt;
Поэтому надо писать конструкторы так, чтобы при возникновении в нем исключения, можно было освободить занятые ресурсы и сообщить об исключении дальше.&lt;br /&gt;
Напомним также, что при нормальной работе программы оператор &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt; не кидает исключений, а оператор &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; может.&lt;br /&gt;
Напишем класс, который освободит выделенную память если произошло исключение в конструкторе. &lt;br /&gt;
Здесь же используется специальный синтаксис для перехвата исключений в списке инициализации.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct A&lt;br /&gt;
{&lt;br /&gt;
	int* p1;&lt;br /&gt;
	int* p2;&lt;br /&gt;
&lt;br /&gt;
	A(size_t p1_sz, size_t p2_sz) &lt;br /&gt;
		try&lt;br /&gt;
		:	p1(new int[p1_sz])&lt;br /&gt;
		,	p2(0)&lt;br /&gt;
	{&lt;br /&gt;
		try&lt;br /&gt;
		{&lt;br /&gt;
			p2 = new int[p2_sz];&lt;br /&gt;
		}&lt;br /&gt;
		catch(...)&lt;br /&gt;
		{&lt;br /&gt;
			delete[] p1; //only p1 allocated&lt;br /&gt;
			throw;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	catch(...)&lt;br /&gt;
	{&lt;br /&gt;
		//no memory allocated&lt;br /&gt;
		throw;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	~A()&lt;br /&gt;
	{&lt;br /&gt;
		delete[] p1;&lt;br /&gt;
		delete[] p2;&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Упражнение:&lt;br /&gt;
Опеределить сколько исключений может быть брошено в следующем участке кода, если a и b - экземпляры произвольных типов данных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
	if (a + b == c + d)&lt;br /&gt;
	{&lt;br /&gt;
		return a * b;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подсказка: учтите что вызываются операторы приведения типов, +, *, ==.&lt;br /&gt;
&lt;br /&gt;
== Гарантии, которые может предоставлять код по отношению к исключениям ==&lt;br /&gt;
Далее будет удобно оперировать понятием объекта, но все сказанное также относится и к обычным функциям.&lt;br /&gt;
Код, который мы пишем и используем, при возникновении внутри себя исключений может вести себя по разному. Это поведение и определяют уровни гарантий исключений.&lt;br /&gt;
Они специфицируют каким будет поведение кода и каково будет состояние объекта по отношению к внешнему миру, после возникновения в нем исключения. Рассмотрим их.&lt;br /&gt;
&lt;br /&gt;
* Гарантия отсутствия исключений. Такая гарантия специфицирует, что либо ошибок нет, либо все ошибки обрабатываются и объект выполняет все требуемые функции.&lt;br /&gt;
* Строгая гарантия исключений (транзакционность). Объект после обработки ошибки возвращается в состояние перед вызовом метода, в котором она возникла. Если мы выполняем ввод\вывод, то гарантировать строгую гарантию невозможно без очень сложных мероприятий.&lt;br /&gt;
* Базовая гарантия. После обработки исключения оказываемся в любом другом согласованном состоянии.&lt;br /&gt;
&lt;br /&gt;
Напишем неполный класс массива, который реализует строгую гарантию исключений при копировании через конструктор.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
template&amp;lt;typename T&amp;gt;&lt;br /&gt;
struct Array&lt;br /&gt;
{&lt;br /&gt;
	Array(size_t size)&lt;br /&gt;
		:	size_(size)&lt;br /&gt;
		,	data_(new T[size])&lt;br /&gt;
	{}&lt;br /&gt;
&lt;br /&gt;
	Array(Array const &amp;amp; src)&lt;br /&gt;
	{&lt;br /&gt;
		T* old_data = data_;&lt;br /&gt;
		size_t old_size = size_;&lt;br /&gt;
		try&lt;br /&gt;
		{&lt;br /&gt;
			data_ = new T[src.size_];&lt;br /&gt;
			size_ = src.size_;&lt;br /&gt;
			for(size_t i = 0; i &amp;lt; size_; ++i)&lt;br /&gt;
				data_[i] = src.data_[i];&lt;br /&gt;
		}&lt;br /&gt;
		catch(...)&lt;br /&gt;
		{&lt;br /&gt;
			delete data_;&lt;br /&gt;
			data_ = old_data;&lt;br /&gt;
			size_ = old_size;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
	T* data_;&lt;br /&gt;
	size_t size_;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%98%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=349</id>
		<title>Обсуждение:Исключения</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%98%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=349"/>
				<updated>2011-06-01T07:45:43Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Мне кажется, что вместо 24/7/365 стоит написать просто 24/7. Так как в году 365 '''дней''' (и то только в чуть больше чем 75% случаев), а не '''недель'''.&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%98%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=348</id>
		<title>Обсуждение:Исключения</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%98%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F&amp;diff=348"/>
				<updated>2011-06-01T07:43:59Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: Новая страница: «Мне кажется, что вместо 24/7/365 стоит написать просто 24/7. Так как в году 365 '''дней''' (и то только…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Мне кажется, что вместо 24/7/365 стоит написать просто 24/7. Так как в году 365 '''дней''' (и то только в менее чем 75% случаев), а не '''недель'''&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2._RTTI&amp;diff=331</id>
		<title>Приведение типов. RTTI</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2._RTTI&amp;diff=331"/>
				<updated>2011-05-30T18:13:22Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Приведение типов==&lt;br /&gt;
Приведение типов делится на C style cast и C++ style cast&lt;br /&gt;
===Приведение в стиле C===&lt;br /&gt;
Синтаксис приведения:&lt;br /&gt;
* (тип_к_которому_приводим) переменная&lt;br /&gt;
* тип_к_которому_приводим (переменная)&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
double d = (double) i;&lt;br /&gt;
float f = float(i);&lt;br /&gt;
char const* ch = &amp;quot;hello&amp;quot;;&lt;br /&gt;
string str = (string) ch;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Приведение в стиле С++===&lt;br /&gt;
В С++ для приведения типов используются следующие функции:&lt;br /&gt;
* const_cast&lt;br /&gt;
* reinterpret_cast&lt;br /&gt;
* static_cast&lt;br /&gt;
* dynamic_cast&lt;br /&gt;
Во всех случаях синтаксис приведения будет выглядеть следующим образом:&lt;br /&gt;
..._cast &amp;lt;тип_к_которому_приводим&amp;gt; (переменная)&lt;br /&gt;
&lt;br /&gt;
Рассмотрим первые три более подробно (dynamic_cast рассматривается в разделе RTTI).&lt;br /&gt;
====const_cast====&lt;br /&gt;
Добавляет/убирает у объекта константность. Если убрать константность у объекта, который был объявлен как константный, то при записи может возникнуть undefined behavior (в зависимости от типа объекта).&lt;br /&gt;
&lt;br /&gt;
Рассмотрим ситуацию, когда нам может пригодиться const_cast.&lt;br /&gt;
Предположим у нас класс A, в котором хранятся элементы типа Т. Пусть требуется реализовать метод get (константный и не константный), который по индексу i будет возвращать i-ый элемент. Можно описать реализацию только одного метода (константного), а второй реализовать через вызов первого при помощи const_cast:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
T const&amp;amp; get (int i) const;&lt;br /&gt;
T&amp;amp;       get (int i) {&lt;br /&gt;
    return const_cast&amp;lt;T&amp;amp;&amp;gt; (const_cast&amp;lt;A const*&amp;gt; (this).get(i) );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====reinterpret_cast====&lt;br /&gt;
Приводит любой указатель к любому указателю.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Point3 {&lt;br /&gt;
    double x;&lt;br /&gt;
    double y;&lt;br /&gt;
    double z;&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
Point3* p = ...;&lt;br /&gt;
double* p_x = reinterpret_cast&amp;lt;double*&amp;gt; (p);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Замечание: приведенный пример отработает корректно в случае если структура Point3 плотно упакована в памяти (см. опции компилятора).&lt;br /&gt;
====static_cast====&lt;br /&gt;
Используется для приведения&lt;br /&gt;
* числовых типов (аналогично C-style cast)&lt;br /&gt;
* указателей и ссылок для классов связанных наследованием&lt;br /&gt;
* пользовательских преобразований&lt;br /&gt;
Преобразование выполняется в момент компиляции и run-time проверки (как это есть в dynamic_cast) приведения типов нет, поэтому сложные приведения типов следует делать очень аккуратно. &lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct A {};&lt;br /&gt;
struct B : A {};&lt;br /&gt;
...&lt;br /&gt;
B* b;&lt;br /&gt;
A* a = static_cast&amp;lt;A*&amp;gt; (b);&lt;br /&gt;
b = static_cast&amp;lt;B*&amp;gt; (a);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Замечание: static_cast меняет указатель в зависимости от того какое у классов наследование (в отличии от reinterpret_cast), поэтому если будет forward declaration, то static_cast выдаст ошибку (на этапе компиляции):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct A;&lt;br /&gt;
struct B;&lt;br /&gt;
B* b;&lt;br /&gt;
A* a = static_cast&amp;lt;A*&amp;gt;(b); // ошибка!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Общее замечание по разделу Приведение типов:&lt;br /&gt;
При программировании на С++ рекомендуется использовать C-style cast только в случаях приведения элементарных типов друг к другу.&lt;br /&gt;
&lt;br /&gt;
==RTTI==&lt;br /&gt;
RTTI расшифровывается как Run-time type information. Это механизм, позволяющий определять тип объекта в момент выполнения программы. В С++ данный механизм реализуется при помощи следующих элементов:&lt;br /&gt;
* оператор dynamic_cast (используется для преобразования полиморфных типов)&lt;br /&gt;
* оператор typeid (для точного определения типа объекта)&lt;br /&gt;
* класс type_info (для хранения информации, возвращаемой оператором typeid)&lt;br /&gt;
&lt;br /&gt;
Рассмотрим применение и синтаксис typeid и type_info на примере:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;typeinfo&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
A* a;&lt;br /&gt;
type_info&amp;amp; ti = typeid(a);&lt;br /&gt;
std::cout &amp;lt;&amp;lt; ti.name() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Более сложный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;typeinfo&amp;gt;&lt;br /&gt;
struct A {};&lt;br /&gt;
struct B : A {};&lt;br /&gt;
...&lt;br /&gt;
A* a = new B();&lt;br /&gt;
typeid(a);  // A*&lt;br /&gt;
typeid(*a); // B&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
У класса type_info помимо метода name (возвращающего строку - char*, характеризующую тип объекта) и операторов равенства/неравенства есть еще метод before, который позволяет упорядочивать экземпляры type_info и хранить их, например, в map.&lt;br /&gt;
&lt;br /&gt;
===dynamic_cast===&lt;br /&gt;
Позволяет приводить указатель или объект одного типа к указателю или ссылке на другой класс (связанный с первым через наследование).&lt;br /&gt;
В отличии от static_cast выполняется в run-time.&lt;br /&gt;
При ошибке приведения к указателю на тип dynamic_cast возвращает нулевой указатель, при ошибке приведения к ссылке на тип выбрасывается исключение bad_cast.&lt;br /&gt;
&lt;br /&gt;
Пример использования:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct A {&lt;br /&gt;
	virtual void f() {}&lt;br /&gt;
};&lt;br /&gt;
struct B : A {&lt;br /&gt;
	virtual void f() {}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
A* pa = new B;&lt;br /&gt;
A* pa2 = new A;&lt;br /&gt;
&lt;br /&gt;
B* pb = dynamic_cast&amp;lt;B*&amp;gt;(pa);   // pb указывает на B&lt;br /&gt;
B* pb2 = dynamic_cast&amp;lt;B*&amp;gt;(pa2); // pb2 указывает на А, а не на В!&lt;br /&gt;
&lt;br /&gt;
pb-&amp;gt;f();&lt;br /&gt;
pb2-&amp;gt;f(); // ошибка на этапе исполнения!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Замечание: При приведении к указателю на void возвращается указатель на начало блока.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Общие замечания по разделу RTTI:&lt;br /&gt;
* почти всегда можно обойтись без RTTI и чаще всего использование этого механизма говорит об ошибке проектирования&lt;br /&gt;
* на этапе отладки применение RTTI бывает полезно.&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2._RTTI&amp;diff=330</id>
		<title>Приведение типов. RTTI</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2._RTTI&amp;diff=330"/>
				<updated>2011-05-30T17:40:09Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: Новая страница: «==Приведение типов== Приведение типов делится на C style cast и C++ style cast ===Приведение в стиле C=== С…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Приведение типов==&lt;br /&gt;
Приведение типов делится на C style cast и C++ style cast&lt;br /&gt;
===Приведение в стиле C===&lt;br /&gt;
Синтаксис приведения:&lt;br /&gt;
* (тип_к_которому_приводим) переменная&lt;br /&gt;
* тип_к_которому_приводим (переменная)&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int i = 10;&lt;br /&gt;
double d = (double) i;&lt;br /&gt;
float f = float(i);&lt;br /&gt;
char const* ch = &amp;quot;hello&amp;quot;;&lt;br /&gt;
string str = (string) ch;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Приведение в стиле С++===&lt;br /&gt;
В С++ для приведения типов используются следующие функции:&lt;br /&gt;
* const_cast&lt;br /&gt;
* reinterpret_cast&lt;br /&gt;
* static_cast&lt;br /&gt;
* dynamic_cast&lt;br /&gt;
Во всех случаях синтаксис приведения будет выглядеть следующим образом:&lt;br /&gt;
..._cast &amp;lt;тип_к_которому_приводим&amp;gt; (переменная)&lt;br /&gt;
&lt;br /&gt;
Рассмотрим первые три более подробно (dynamic_cast рассматривается в разделе RTTI).&lt;br /&gt;
====const_cast====&lt;br /&gt;
Добавляет/убирает у объекта константность. Если убрать константность у объекта, который был объявлен как константный, то при записи может возникнуть undefined behavior (в зависимости от типа объекта).&lt;br /&gt;
&lt;br /&gt;
Рассмотрим ситуацию, когда нам может пригодиться const_cast.&lt;br /&gt;
Предположим у нас класс A, в котором хранятся элементы типа Т. Пусть требуется реализовать метод get (константный и не константный), который по индексу i будет возвращать i-ый элемент. Можно описать реализацию только одного метода (константного), а второй реализовать через вызов первого при помощи const_cast:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
T const&amp;amp; get (int i) const;&lt;br /&gt;
T&amp;amp;       get (int i) {&lt;br /&gt;
    return const_cast&amp;lt;T&amp;amp;&amp;gt; (const_cast&amp;lt;A const*&amp;gt; (this).get(i) );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====reinterpret_cast====&lt;br /&gt;
Приводит любой указатель к любому указателю.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Point3 {&lt;br /&gt;
    double x;&lt;br /&gt;
    double y;&lt;br /&gt;
    double z;&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
Point3* p = ...;&lt;br /&gt;
double* p_x = reinterpret_cast&amp;lt;double*&amp;gt; (p);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Замечание: приведенный пример отработает корректно в случае если структура Point3 плотно упакована в памяти (см. опции компилятора).&lt;br /&gt;
====static_cast====&lt;br /&gt;
Используется для приведения&lt;br /&gt;
* числовых типов (аналогично C-style cast)&lt;br /&gt;
* указателей и ссылок для классов связанных наследованием&lt;br /&gt;
* пользовательских преобразований&lt;br /&gt;
Преобразование выполняется в момент компиляции и run-time проверки (как это есть в dynamic_cast) приведения типов нет, поэтому сложные приведения типов следует делать очень аккуратно. &lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct A {};&lt;br /&gt;
struct B : A {};&lt;br /&gt;
...&lt;br /&gt;
B* b;&lt;br /&gt;
A* a = static_cast&amp;lt;A*&amp;gt; (b);&lt;br /&gt;
b = static_cast&amp;lt;B*&amp;gt; (a);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Замечание: static_cast меняет указатель в зависимости от того какое у классов наследование (в отличии от reinterpret_cast), поэтому если будет forward declaration, то static_cast выдаст ошибку (на этапе компиляции):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct A;&lt;br /&gt;
struct B;&lt;br /&gt;
B* b;&lt;br /&gt;
A* a = static_cast&amp;lt;A*&amp;gt;(b); // ошибка!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Общее замечание по разделу Приведение типов:&lt;br /&gt;
При программировании на С++ рекомендуется использовать C-style cast только в случаях приведения элементарных типов друг к другу.&lt;br /&gt;
&lt;br /&gt;
==RTTI==&lt;br /&gt;
RTTI расшифровывается как Run-time type information. Это механизм, позволяющий определять тип объекта в момент выполнения программы. В С++ данный механизм реализуется при помощи следующих элементов:&lt;br /&gt;
* оператор dynamic_cast (используется для преобразования полиморфных типов)&lt;br /&gt;
* оператор typeid (для точного определения типа объекта)&lt;br /&gt;
* класс type_info (для хранения информации, возвращаемой оператором typeid)&lt;br /&gt;
&lt;br /&gt;
Рассмотрим применение и синтаксис typeid и type_info на примере:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;typeinfo&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
A* a;&lt;br /&gt;
type_info&amp;amp; ti = typeid(a);&lt;br /&gt;
std::cout &amp;lt;&amp;lt; ti.name() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Более сложный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;typeinfo&amp;gt;&lt;br /&gt;
struct A {};&lt;br /&gt;
struct B : A {};&lt;br /&gt;
...&lt;br /&gt;
A* a = new B();&lt;br /&gt;
typeid(a);  // A*&lt;br /&gt;
typeid(*a); // B&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
У класса type_info помимо метода name (возвращающего строку - char*, характеризующую тип объекта) и операторов равенства/неравенства есть еще метод before, который позволяет упорядочивать экземпляры type_info и хранить их например в map.&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9A%D0%BE%D0%BD%D1%81%D0%BF%D0%B5%D0%BA%D1%82%D1%8B_%D0%A1%2B%2B&amp;diff=309</id>
		<title>Конспекты С++</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9A%D0%BE%D0%BD%D1%81%D0%BF%D0%B5%D0%BA%D1%82%D1%8B_%D0%A1%2B%2B&amp;diff=309"/>
				<updated>2011-05-30T08:46:32Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: /* 2 семестр (зима-весна 2011) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 1 семестр (осень-зима 2010) ==&lt;br /&gt;
&lt;br /&gt;
* [[ Как происходит компиляция|Как происходит компиляция. Алексей Давыдов. 08.09.2010]]&lt;br /&gt;
* [[ Указатели и ссылки|Указатели и ссылки. Екатерина Полищук. 10.09.2010]]&lt;br /&gt;
* [[ Динамическое распределение памяти|Динамическое распределение памяти. Алексей Гуревич. 17.09.2010]]&lt;br /&gt;
* [[ Классы|Классы. Курьян Кристина. 08.10.2010]]&lt;br /&gt;
* [[ Перегрузка операторов|Перегрузка операторов. Мария Фомкина. 12.11.2010]]&lt;br /&gt;
* [[ Множественное наследование, дружба|Множественное наследование, дружба Евгений Баталов. 02.12.2010]]&lt;br /&gt;
&lt;br /&gt;
== 2 семестр (зима-весна 2011) ==&lt;br /&gt;
&lt;br /&gt;
* [[ Напоминание про inline и static. Синглтон.|Напоминание про inline и static. Синглтон. Екатерина Полищук. 11.02.2011]]&lt;br /&gt;
* [[ STL. Последовательные контейнеры|STL. Последовательные контейнеры. Мария Фомкина. 18.02.2011]]&lt;br /&gt;
* [[ Ассоциативные контейнеры |STL. Ассоциативные контейнеры. Светлана Марченко. 25.02.2011]]&lt;br /&gt;
* [[ Итераторы и алгоритмы | Итераторы и алгоритмы. Всеволод Опарин. 04.03.2011]]&lt;br /&gt;
* [[ Функторы, часть вторая. Иван Близнец. когда-то | Функторы. Namespaces. Иван Близнец. 09.03.2011 ]]&lt;br /&gt;
* [[ Указатели на функции|Указатели на функции. Курьян Кристина. 18.03.2011]]&lt;br /&gt;
* [[ Исключения | Методы обработки ошибок. Исключения. Гарантии исключений. Евгений Баталов. 01.04.2011 ]]&lt;br /&gt;
* [[ Приведение типов. RTTI | Приведение типов. RTTI. Алексей Гуревич. 15.04.2011 ]]&lt;br /&gt;
* [[ Метапрограммирование на C++ | Метапрограммирование на C++. Александр Карташов. 06.05.2011 ]]&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F_%D0%BF%D0%BE_%D0%A1%2B%2B&amp;diff=157</id>
		<title>Задания по С++</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F_%D0%BF%D0%BE_%D0%A1%2B%2B&amp;diff=157"/>
				<updated>2011-03-30T07:35:26Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: /* Лабораторная работа №4 iterator */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Лабораторная работа №1 Шаблоны ==&lt;br /&gt;
Реализовать собственный контейнер &lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;
class Container {&lt;br /&gt;
public:&lt;br /&gt;
    void push_back(const T&amp;amp; t);&lt;br /&gt;
    T&amp;amp; back();&lt;br /&gt;
    size_t size() const;&lt;br /&gt;
};&amp;lt;/source&amp;gt;&lt;br /&gt;
В качестве хранилища значенией в реализации &amp;lt;code&amp;gt;Container&amp;lt;/code&amp;gt; используйте &amp;lt;code&amp;gt;std::vector&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Затем создайте новый контейнер с двумя шаблонными параметрами, первый - тип хранимых значений, второй - тип хранилища, используемый в реализации вашего контейнера.&lt;br /&gt;
&lt;br /&gt;
Пример использования такого контейнера&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Container&amp;lt;int, std::list&amp;lt;int&amp;gt; &amp;gt; c;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Затем создайте новый контейнер с двумя шаблонными параметрами, первый - тип хранимых значений, второй - шаблон, используемый в реализации вашего контейнера.&lt;br /&gt;
&lt;br /&gt;
Пример использования такого контейнера&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Container&amp;lt;int, std::deque&amp;gt; c;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Лабораторная работа №2 Синглтон ==&lt;br /&gt;
&lt;br /&gt;
Написать протой логгер&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;class Logger {&lt;br /&gt;
public:&lt;br /&gt;
    void warn(const std::string&amp;amp; msg);&lt;br /&gt;
    static Logger&amp;amp; getInstance();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Запретить пользователю его создание, копирование.&lt;br /&gt;
&lt;br /&gt;
Пример использования&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Logger&amp;amp; log = Logger::getInstance();&lt;br /&gt;
log.warn(&amp;quot;Ooops&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Представить, что понадобилось ещё несколько синглтонов, вынести общий для всех синглтонов код в отдельный класс &amp;lt;code&amp;gt;Singleton&amp;lt;/code&amp;gt;.&lt;br /&gt;
Реализовать логгер с использованием класса &amp;lt;code&amp;gt;Singleton&amp;lt;/code&amp;gt; так, чтоб код, использующий логгер, не надо было модифицировать.&lt;br /&gt;
&lt;br /&gt;
== Лабораторная работа №3 merge sort ==&lt;br /&gt;
Необходимо написать функцию сортировки слиянием.&amp;lt;br /&amp;gt;&lt;br /&gt;
Сигнатура функции должны быть такой:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;template&amp;lt;typename Iter&amp;gt;&lt;br /&gt;
std::list&amp;lt;typename Iter::value_type&amp;gt; mergeSort(Iter left, Iter right);&amp;lt;/source&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Исходные данные функция модифицировать не должна, в возвращаемом списке должны быть отсортированные элементы.&lt;br /&gt;
&lt;br /&gt;
Затем необходимо добиться, чтоб можно было сортировать по указателям:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;int* array = new int[SIZE];&lt;br /&gt;
mergeSort(array, array + SIZE);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Рекомендации'': для merge можно воспользоваться &amp;lt;code&amp;gt;std::list::merge&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
для получения типа, на который указывает указатель, можно воспользоваться &amp;lt;code&amp;gt;std::iterator_traits&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Лабораторная работа №4 iterator ==&lt;br /&gt;
Написать шаблонный класс &amp;lt;code&amp;gt;slist&amp;lt;/code&amp;gt; односвязный список.&amp;lt;br /&amp;gt;&lt;br /&gt;
Реализовать для него &amp;lt;code&amp;gt;forward&amp;lt;/code&amp;gt; итератор.&lt;br /&gt;
&lt;br /&gt;
== Лабораторная работа №5 functor ==&lt;br /&gt;
Реализовать алгоритм &lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
template&amp;lt;typename InIter, typename OutIter, typename Pred&amp;gt;&lt;br /&gt;
OutIter filter(InIter begin, InIter end, OutIter out, Pred pred);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
который читает элементы и, если &amp;lt;code&amp;gt;pred(val)&amp;lt;/code&amp;gt; возвращает &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, то записывает элемент в &amp;lt;code&amp;gt;out&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Реализовать собственный функтор, который принимает &amp;lt;code&amp;gt;std::set&amp;lt;char&amp;gt;&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; и проверят наличие входного символа в сете.&lt;br /&gt;
С помощью алгоритма &amp;lt;code&amp;gt;filter&amp;lt;/code&amp;gt; и вашего функтора отфильровать строку.&lt;br /&gt;
&lt;br /&gt;
== Лабораторная работа №6 mem_fun ==&lt;br /&gt;
Реализовать аналог &amp;lt;code&amp;gt;std::mem_fun&amp;lt;/code&amp;gt;, убедиться, что аналог работает на коде:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::vector&amp;lt;char&amp;gt; v;&lt;br /&gt;
std::set&amp;lt;int&amp;gt; s;&lt;br /&gt;
mem_fun(&amp;amp;std::vector&amp;lt;char&amp;gt;::push_back)(v, 'd');&lt;br /&gt;
mem_fun(&amp;amp;std::set&amp;lt;int&amp;gt;::count)(s, 3);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Лабораторная работа №7 заполнитель мапы ==&lt;br /&gt;
Реализовать заполнитель мапы&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
std::map&amp;lt;float, int&amp;gt; m(mapper(1.0, 2)(2, 2)(4, 2));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D1%80%D0%B0%D1%81%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D0%B8&amp;diff=145</id>
		<title>Динамическое распределение памяти</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D1%80%D0%B0%D1%81%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D0%B8&amp;diff=145"/>
				<updated>2011-03-27T19:29:14Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: Новая страница: «== Виды памяти ==  Память, которую использует программа делится на три вида:  1. Статическая п…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Виды памяти ==&lt;br /&gt;
&lt;br /&gt;
Память, которую использует программа делится на три вида:&lt;br /&gt;
&lt;br /&gt;
1. Статическая память (static memory)&lt;br /&gt;
* хранит глобальные переменные и константы;&lt;br /&gt;
* размер определяется при компиляции.&lt;br /&gt;
2. Стек (stack)&lt;br /&gt;
* хранит локальные переменные, аргументы функций и промежуточные значения вычислений;&lt;br /&gt;
* размер определяется при запуске программы (обычно выделяется 4 Мб).&lt;br /&gt;
3. Куча (heap)&lt;br /&gt;
* динамически распределяемая память;&lt;br /&gt;
* ОС выделяет память по частям (по мере необходимости).&lt;br /&gt;
&lt;br /&gt;
Динамически распределяемую память следует использовать в случае если мы заранее (на момент написания программы) не знаем сколько памяти нам понадобится (например, размер массива зависит от того, что введет пользователь во время работы программы) и при работе с большими объемами данных (например, массив из 1 000 000 элементов типа &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; не поместится на стеке).&lt;br /&gt;
&lt;br /&gt;
== Работа с динамической памятью в С ==&lt;br /&gt;
&lt;br /&gt;
Для работы с динамической памятью в языке С используются следующие функции: &amp;lt;code&amp;gt;malloc, calloc, free, realloc&amp;lt;/code&amp;gt;.&lt;br /&gt;
Рассмотрим их подробнее.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void * malloc(size_t size);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В качестве входного параметра функция принимает размер памяти, которую требуется выделить. Возвращаемым значением является указатель на выделенный в куче участок памяти.&lt;br /&gt;
Для выделения памяти под 1 000 000 элементов типа &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; необходимо выполнить следующий код:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int * p = malloc(1000000 * sizeof(int));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В языке С++ потребуется небольшая модификация данной кода (из-за того, что в С++ нет неявного приведения указателей):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int * p = (int *) malloc(1000000 * sizeof(int));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Если ОС не смогла выделить память (например, памяти не хватило), то &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; возвращает 0.&lt;br /&gt;
&lt;br /&gt;
После окончания работы с выделенной динамически памятью нужно освободить ее. Для этой цели используется функция &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt;, которая возвращает память под управление ОС.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void free(void * ptr);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В качестве входного параметра в &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; нужно передать указатель, значение которого получено из функции &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt;. Вызов &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; на указателях полученных не из &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; (например, &amp;lt;code&amp;gt;free(p+10)&amp;lt;/code&amp;gt;) приведет к неопределенному поведению. Это связанно с тем, что при выделении памяти при помощи &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; в ячейки перед той, на которую указывает возвращаемый функцией указатель операционная система записывает служебную информацию (см. рис.). При вызове &amp;lt;code&amp;gt;free(p+10)&amp;lt;/code&amp;gt; информация находящаяся перед ячейкой &amp;lt;code&amp;gt;(p+10)&amp;lt;/code&amp;gt; будет трактоваться как служебная.&lt;br /&gt;
&lt;br /&gt;
[[Файл:pointer_in_heap.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void * calloc(size_t nmemb, size_t size);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Функция работает аналогично &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt;, но отличается синтаксисом (вместо размера выделяемой памяти нужно задать количество элементов и размер одного элемента) и тем, что выделенная память будет обнулена. Например, после выполнения&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int * q = (int *) calloc(1000000, sizeof(int))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; будет указывать на начало массива из миллиона элементов типа &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; проинициализированных нулями.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void * realloc(void * ptr, size_t size);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Функция изменяет размер выделенной памяти (на которую указывает &amp;lt;code&amp;gt;ptr&amp;lt;/code&amp;gt;, полученный из вызова &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;realloc&amp;lt;/code&amp;gt;). Если размер указанный в параметре &amp;lt;code&amp;gt;size&amp;lt;/code&amp;gt; больше, чем тот, который был выделен под указатель &amp;lt;code&amp;gt;ptr&amp;lt;/code&amp;gt;, то проверяется, есть ли возможность выделить недостающие ячейки памяти подряд с уже выделенными. Если места недостаточно, то выделяется новый участок памяти размером &amp;lt;code&amp;gt;size&amp;lt;/code&amp;gt; и данные по указателю &amp;lt;code&amp;gt;ptr&amp;lt;/code&amp;gt; копируются в начало нового участка.&lt;br /&gt;
&lt;br /&gt;
=== Какие бывают ошибки ===&lt;br /&gt;
1. Потеря памяти&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int * p = (int *) malloc(100);&lt;br /&gt;
p = (int *) malloc(200); // потерян указатель на первые 100 &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;'ов, которые теперь нельзя отдать обратно ОС&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2. Повторное освобождение выделенной памяти&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
free(p);&lt;br /&gt;
… &lt;br /&gt;
free(p); // неопределенное поведение&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Правильно:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
free(p);&lt;br /&gt;
p = 0;&lt;br /&gt;
…&lt;br /&gt;
free(p); // отработает без ошибок &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Работа с динамической памятью в С++ ==&lt;br /&gt;
&lt;br /&gt;
В С++ есть свой механизм выделения и освобождения памяти — это функции &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;delete&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пример использования &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int * p = new int[1000000]; // выделение памяти под 1000000 int`ов&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Т.е. при использовании функции &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; не нужно приводить указатель и не нужно использовать &amp;lt;code&amp;gt;sizeof()&amp;lt;/code&amp;gt;.&lt;br /&gt;
Освобождение выделенной при помощи &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; памяти осуществляется посредством следующего вызова:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
delete [] p;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Если требуется выделить память под один элемент, то можно использовать&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int * q = new int;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
или&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int * q = new int(10); // выделенный int проинциализируется значением 10&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
в этом случае удаление будет выглядеть следующим образом:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
delete q;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Замечание:'''  &lt;br /&gt;
&lt;br /&gt;
Выделять динамически небольшие кусочки памяти (например, под один элемент простого типа данных) не целесообразно по двум причинам:&lt;br /&gt;
# При динамическом выделении памяти в ней помимо значения указанного типа будет храниться служебная информация ОС и С/С++. Таким образом потребуется гораздо больше памяти, чем при хранении необходимых данных на стеке.&lt;br /&gt;
# Если в памяти хранить большое количество маленьких кусочков, то она будет сильно фрагментирована и большой массив данных может не поместиться.&lt;br /&gt;
&lt;br /&gt;
=== Многомерные массивы ===&lt;br /&gt;
&amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; позволяет выделять только одномерные массивы, поэтому для работы с многомерными массивами необходимо воспринимать их как массив указателей на другие массивы.&lt;br /&gt;
Для примера рассмотрим задачу выделения динамической памяти под массив чисел размера &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; на &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''1ый способ''' &lt;br /&gt;
 &lt;br /&gt;
На первом шаге выделяется указатель на массив указателей, а на втором шаге, в цикле каждому указателю из массива выделяется массив чисел в памяти:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int ** a = new int*[n];&lt;br /&gt;
for (int i = 0; i != n; ++i)&lt;br /&gt;
  a[i] = new int[m];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Однако, этот способ плох тем, что в нём требуется n+1 выделение памяти, а это достаточно дорогая по времени операция.  &lt;br /&gt;
&lt;br /&gt;
'''2ой способ'''  &lt;br /&gt;
&lt;br /&gt;
На первом шаге выделение массива указателей и массива чисел размером n на m. На втором шаге каждому указателю из массива ставится в соответствие строка в массиве чисел.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int ** a = new int*[n];&lt;br /&gt;
a[0] = new int[n*m];&lt;br /&gt;
for (int i = 1; i != n; ++i)&lt;br /&gt;
  a[i] = a[0] + i*m;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В данном случае требуется всего 2 выделения памяти.&lt;br /&gt;
Для освобождения памяти потребуется выполнить:  &lt;br /&gt;
&lt;br /&gt;
'''1ый способ:'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
for (int i = 0; i != n; ++i)&lt;br /&gt;
  delete [] a[i];&lt;br /&gt;
delete [] a;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''2ой способ:'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
delete [] a[0];&lt;br /&gt;
delete [] a;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Таким образом, второй способ опять же требует гораздо меньше вызовов функции &amp;lt;code&amp;gt;delete []&amp;lt;/code&amp;gt;, чем первый.&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Pointer_in_heap.png&amp;diff=144</id>
		<title>Файл:Pointer in heap.png</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Pointer_in_heap.png&amp;diff=144"/>
				<updated>2011-03-27T19:05:33Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9A%D0%BE%D0%BD%D1%81%D0%BF%D0%B5%D0%BA%D1%82%D1%8B_%D0%A1%2B%2B&amp;diff=143</id>
		<title>Конспекты С++</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9A%D0%BE%D0%BD%D1%81%D0%BF%D0%B5%D0%BA%D1%82%D1%8B_%D0%A1%2B%2B&amp;diff=143"/>
				<updated>2011-03-27T18:46:18Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Конспекты по C++&lt;br /&gt;
* [[ Как происходит компиляция|Как происходит компиляция. Алексей Давыдов. 08.09.2010]]&lt;br /&gt;
* [[ Динамическое распределение памяти|Динамическое распределение памяти. Алексей Гуревич. 17.09.2010]]&lt;br /&gt;
* [[ Перегрузка операторов|Перегрузка операторов. Мария Фомкина. 12.11.2010]]&lt;br /&gt;
* [[ STL. Последовательные контейнеры|STL. Последовательные контейнеры. Мария Фомкина. 18.02.2011]]&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=The_Shortest_Path_Problem&amp;diff=107</id>
		<title>The Shortest Path Problem</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=The_Shortest_Path_Problem&amp;diff=107"/>
				<updated>2011-03-16T23:11:54Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Студент: [[Участник:Alexey.Gurevich|Алексей Гуревич]]&lt;br /&gt;
* Руководитель: Валерий Лесин&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описание: Целью проекта является создание приложения, решающего задачу поиска кратчайшего пути между двумя точками на карте дорог. В приложении должны быть реализованы как классические алгоритмы Дейкстры и A-star, так и их наиболее современные быстрые модификации. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Положение на начало весеннего семестра:&lt;br /&gt;
* разработана графическая оболочка для тестирования алгоритмов,&lt;br /&gt;
* реализованы следующие алгоритмы: &lt;br /&gt;
''  - алгоритм Дейкстры, '' &lt;br /&gt;
&lt;br /&gt;
''   - a-star.'' &lt;br /&gt;
* а также их оптимизации на основе: &lt;br /&gt;
''  - использования двунаправленного поиска,''&lt;br /&gt;
&lt;br /&gt;
''  - якорных точек (landmark) - ALT,''&lt;br /&gt;
&lt;br /&gt;
''  - подсчета достижимости (reach) -  REAL.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагаемые этапы:&lt;br /&gt;
* ускорение алгоритма подсчета достижимости (использование механизма shortcut, распараллеливание вычилений),&lt;br /&gt;
* исследование и реализация алгоритмов &amp;quot;contraction hierarchies&amp;quot; (начало апреля),&lt;br /&gt;
* исследование и реализация алгоритмов &amp;quot;transit node routing&amp;quot; (начало мая),&lt;br /&gt;
* &amp;lt;возможный этап&amp;gt; слияние с [[Shortest_Path_Service|проектом]] [[Участник:Eabatalov89|Евгения Баталова]] (АУ, кафедра SE, 5 курс) с целью создание многопользовательского приложения с web-интерфейсом для поиска кратчайших путей на графе дорог на основе разработанных алгоритмов. (конец мая)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ожидаемый результат:&lt;br /&gt;
* Приложение, реализующее быстрый поиск кратчайших путей между двумя точками на графе дорог.&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=The_Shortest_Path_Problem&amp;diff=83</id>
		<title>The Shortest Path Problem</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=The_Shortest_Path_Problem&amp;diff=83"/>
				<updated>2011-03-13T22:56:27Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Студент: Алексей Гуревич &lt;br /&gt;
* Руководитель: Валерий Лесин&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описание: Целью проекта является создание приложения, решающего задачу поиска кратчайшего пути между двумя точками на карте дорог. В приложении должны быть реализованы как классические алгоритмы Дейкстры и A-star, так и их наиболее современные быстрые модификации. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Положение на начало весеннего семестра:&lt;br /&gt;
* разработана графическая оболочка для тестирования алгоритмов,&lt;br /&gt;
* реализованы следующие алгоритмы: &lt;br /&gt;
''  - алгоритм Дейкстры, '' &lt;br /&gt;
&lt;br /&gt;
''   - a-star.'' &lt;br /&gt;
* а также их оптимизации на основе: &lt;br /&gt;
''  - использования двунаправленного поиска,''&lt;br /&gt;
&lt;br /&gt;
''  - якорных точек (landmark) - ALT,''&lt;br /&gt;
&lt;br /&gt;
''  - подсчета достижимости (reach) -  REAL.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагаемые этапы:&lt;br /&gt;
* ускорение алгоритма подсчета достижимости (использование механизма shortcut, распараллеливание вычилений),&lt;br /&gt;
* исследование и реализация алгоритмов &amp;quot;contraction hierarchies&amp;quot; (начало апреля),&lt;br /&gt;
* исследование и реализация алгоритмов &amp;quot;transit node routing&amp;quot; (начало мая),&lt;br /&gt;
* &amp;lt;возможный этап&amp;gt; слияние с проектом Евгения Баталова (АУ, кафедра SE, 5 курс) с целью создание многопользовательского приложения с web-интерфейсом для поиска кратчайших путей на графе дорог на основе разработанных алгоритмов. (конец мая)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ожидаемый результат:&lt;br /&gt;
* Приложение, реализующее быстрый поиск кратчайших путей между двумя точками на графе дорог.&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=The_Shortest_Path_Problem&amp;diff=82</id>
		<title>The Shortest Path Problem</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=The_Shortest_Path_Problem&amp;diff=82"/>
				<updated>2011-03-13T22:47:37Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: Новая страница: «* Студент: Алексей Гуревич  * Руководитель: Валерий Лесин  Описание: Целью проекта является …»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Студент: Алексей Гуревич &lt;br /&gt;
* Руководитель: Валерий Лесин&lt;br /&gt;
&lt;br /&gt;
Описание: Целью проекта является создание приложения, решающего задачу поиска кратчайшего пути между двумя точками на карте дорог. В приложении должны быть реализованы как классические алгоритмы Дейкстры и A-star, так и их наиболее современные быстрые модификации. &lt;br /&gt;
&lt;br /&gt;
Положение на начало весеннего семестра:&lt;br /&gt;
* разработана графическая оболочка для тестирования алгоритмов,&lt;br /&gt;
* реализованы следующие алгоритмы: &lt;br /&gt;
&amp;lt;nowiki&amp;gt;  - алгоритм Дейкстры, &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;  - a-star. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* а также их оптимизации на основе: &lt;br /&gt;
&amp;lt;nowiki&amp;gt;  - использования двунаправленного поиска,&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;  - якорных точек (landmark) - ALT,&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;  - подсчета достижимости (reach) -  REAL.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Предполагаемые этапы:&lt;br /&gt;
* ускорение алгоритма подсчета достижимости (использование механизма shortcut, распараллеливание вычилений),&lt;br /&gt;
* исследование и реализация алгоритмов &amp;quot;contraction hierarchies&amp;quot; (начало апреля),&lt;br /&gt;
* исследование и реализация алгоритмов &amp;quot;transit node routing&amp;quot; (начало мая),&lt;br /&gt;
* &amp;lt;возможный этап&amp;gt; слияние с проектом Евгения Баталова (АУ, кафедра SE, 5 курс) с целью создание многопользовательского приложения с web-интерфейсом для поиска кратчайших путей на графе дорог на основе разработанных алгоритмов. (конец мая)&lt;br /&gt;
&lt;br /&gt;
Ожидаемый результат:&lt;br /&gt;
* Приложение, реализующее быстрый поиск кратчайших путей между двумя точками на графе дорог.&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A2%D0%B5%D0%BC%D1%8B_%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA&amp;diff=81</id>
		<title>Темы практик</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A2%D0%B5%D0%BC%D1%8B_%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA&amp;diff=81"/>
				<updated>2011-03-13T22:42:49Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;На этой странице собраны темы индивидуальных и командных проектов. &lt;br /&gt;
&lt;br /&gt;
== Весна 2011 ==&lt;br /&gt;
&lt;br /&gt;
* [[Genome assembler]] (Mariya Fomkina)&lt;br /&gt;
&lt;br /&gt;
* [[Анализ изображений с целью поиска похожих лиц]] (Екатерина Полищук)&lt;br /&gt;
&lt;br /&gt;
* [[The Shortest Path Problem]] (Алексей Гуревич)&lt;br /&gt;
&lt;br /&gt;
== Пул свободных тем ==&lt;br /&gt;
&lt;br /&gt;
* [[GeoToDo list]]&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA%D0%BE%D0%B2%D1%8B%D0%B5_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B&amp;diff=78</id>
		<title>Поисковые системы</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA%D0%BE%D0%B2%D1%8B%D0%B5_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B&amp;diff=78"/>
				<updated>2011-03-13T17:03:20Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Предлагается провести семинар по поисковым системам по базам данных (не про веб-поиск). Формат: много мини-докладов в один день и создание соответствующих страниц в wiki.&lt;br /&gt;
В качестве первого этапа предлагается составить список тем, которые можно было бы обсудить. Сейчас можно только предлагать темы, распределять их будем наследующем этапе.&lt;br /&gt;
&lt;br /&gt;
 * Механизм, архитектура поисковой системы с 3 потоками управления: обработка пользовательских запросов, исполнение запросов, индексирование новых данных.&lt;br /&gt;
 * Алгоритм обратных индексов.&lt;br /&gt;
 * Кластеризация в Data Mining&lt;br /&gt;
 * напиши название темы здесь&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Alexey.Gurevich&amp;diff=77</id>
		<title>Участник:Alexey.Gurevich</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Alexey.Gurevich&amp;diff=77"/>
				<updated>2011-03-12T23:24:45Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: Новая страница: «Алексей Гуревич  [mailto:alexeigurevich@gmail.com alexeigurevich@gmail.com]  200px»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алексей Гуревич&lt;br /&gt;
&lt;br /&gt;
[mailto:alexeigurevich@gmail.com alexeigurevich@gmail.com]&lt;br /&gt;
&lt;br /&gt;
[[Файл:Gurevich.JPG|200px]]&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Gurevich.JPG&amp;diff=76</id>
		<title>Файл:Gurevich.JPG</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Gurevich.JPG&amp;diff=76"/>
				<updated>2011-03-12T23:23:50Z</updated>
		
		<summary type="html">&lt;p&gt;Alexey.Gurevich: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Alexey.Gurevich</name></author>	</entry>

	</feed>