<?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=Katepol</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=Katepol"/>
		<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/Katepol"/>
		<updated>2026-04-06T09:56:32Z</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%D1%86%D0%B0:Katepol&amp;diff=377</id>
		<title>Участница:Katepol</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%D1%86%D0%B0:Katepol&amp;diff=377"/>
				<updated>2011-09-17T08:26:33Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Екатерина Полищук */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Екатерина Полищук ==&lt;br /&gt;
[mailto:katepol14@gmail.com katepol14@gmail.com]&lt;br /&gt;
&lt;br /&gt;
[[Файл:Kate1.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
''Образование''&lt;br /&gt;
&lt;br /&gt;
* 2006-2010 гг Санкт-Петербургский Государственный Политехнический Университет, Факультет Технической Кибренетики, кафедра Информационных и Управляющих Систем.&lt;br /&gt;
&lt;br /&gt;
''Опыт работы''&lt;br /&gt;
&lt;br /&gt;
* 08/2009-12/2009 [http://www.totalobjects.co.uk/ Total Objects]&lt;br /&gt;
.NET Developer.&lt;br /&gt;
* 07/2011-today   [http://www.jetbrains.com/ JetBrains]&lt;br /&gt;
Java Developer. Занимаюсь разработкой [http://www.gnu.org/software/emacs/ Emacs] плагина для [http://www.jetbrains.com/idea/ Intellij Idea].  &lt;br /&gt;
&lt;br /&gt;
''Проекты''&lt;br /&gt;
&lt;br /&gt;
* [http://code.google.com/p/practice2010/ Naive Bayesian Classifier] -  simple web pages classifier.&lt;br /&gt;
* [https://github.com/SmartHub/ExcursionOrganizer Excursion Organizer] - web service for excursion organization in St. Petersburg. Командный проект совместно со [http://mit.spbau.ru/sewiki/index.php/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Svetlana_Marchenko Светой Марченко], [http://mit.spbau.ru/sewiki/index.php/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Aleksandr.kartashov Сашей Карташовым], [http://mit.spbau.ru/sewiki/index.php/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Alexey.Gurevich Лешей Гуревичем], и Пашей Синай.&lt;br /&gt;
* [https://github.com/katepol/PanoramaRecognition Panorama Recognition] - recognition of panorama parts using OpenCV.&lt;/div&gt;</summary>
		<author><name>Katepol</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%D1%86%D0%B0:Katepol&amp;diff=376</id>
		<title>Участница:Katepol</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%D1%86%D0%B0:Katepol&amp;diff=376"/>
				<updated>2011-09-17T08:03:09Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Екатерина Полищук */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Екатерина Полищук ==&lt;br /&gt;
[mailto:katepol14@gmail.com katepol14@gmail.com]&lt;br /&gt;
&lt;br /&gt;
[[Файл:Kate1.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
Образование:&lt;br /&gt;
&lt;br /&gt;
* 2006-2010 гг Санкт-Петербургский Государственный Политехнический Университет, Факультет Технической Кибренетики, кафедра Информационных и Управляющих Систем.&lt;br /&gt;
&lt;br /&gt;
Опыт работы:&lt;br /&gt;
&lt;br /&gt;
* 08/2009-12/2009 [http://www.totalobjects.co.uk/ Total Objects]&lt;br /&gt;
.NET Developer&lt;br /&gt;
* 07/2011-today   [http://www.jetbrains.com/ JetBrains]&lt;br /&gt;
Java Developer. Занимаюсь разработкой [http://www.gnu.org/software/emacs/ Emacs] плагина для [http://www.jetbrains.com/idea/ Intellij Idea].  &lt;br /&gt;
&lt;br /&gt;
Готовые проекты можно найти здесь:&lt;br /&gt;
&lt;br /&gt;
* [http://code.google.com/p/practice2010/ Naive Bayesian Classifier] -  simple web pages classifier.&lt;br /&gt;
* [https://github.com/katepol/PanoramaRecognition Panorama Recognition] - recognition of panorama parts using OpenCV.&lt;/div&gt;</summary>
		<author><name>Katepol</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%D1%86%D0%B0:Katepol&amp;diff=375</id>
		<title>Участница:Katepol</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%D1%86%D0%B0:Katepol&amp;diff=375"/>
				<updated>2011-09-17T08:00:26Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Екатерина Полищук ==&lt;br /&gt;
[mailto:katepol14@gmail.com katepol14@gmail.com]&lt;br /&gt;
&lt;br /&gt;
[[Файл:Kate1.jpg|200px|right]]&lt;br /&gt;
&lt;br /&gt;
Образование:&lt;br /&gt;
&lt;br /&gt;
* 2006-2010 гг Санкт-Петербургский Государственный Политехнический Университет, Факультет Технической Кибренетики, кафедра Информационных и Управляющих Систем.&lt;br /&gt;
&lt;br /&gt;
Опыт работы:&lt;br /&gt;
&lt;br /&gt;
* 08/2009-12/2009 [www.totalobjects.co.uk Total Objects]&lt;br /&gt;
.NET Developer&lt;br /&gt;
* 07/2011-today   [http://www.jetbrains.com/ JetBrains]&lt;br /&gt;
Java Developer. Занимаюсь разработкой [http://www.gnu.org/software/emacs/ Emacs] плагина для [http://www.jetbrains.com/idea/ Intellij Idea].  &lt;br /&gt;
&lt;br /&gt;
Готовые проекты можно найти здесь:&lt;br /&gt;
&lt;br /&gt;
* [http://code.google.com/p/practice2010/ Naive Bayesian Classifier] -  simple web pages classifier.&lt;br /&gt;
* [https://github.com/katepol/PanoramaRecognition Panorama Recognition] - recognition of panorama parts using OpenCV.&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=201</id>
		<title>Напоминание про inline и static. Синглтон.</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=201"/>
				<updated>2011-05-02T10:09:57Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Синглтон */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Inline==&lt;br /&gt;
Рассмотрим некоторую inline функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
inline void f() {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Где ее разместить: в cpp или в header'e?'''&lt;br /&gt;
&lt;br /&gt;
1) При размещении любой функции в заголовочном файле, если данный header включен в несколько файлов вашего проекта, проект упадет при линковке, если ваша функция не inline.&lt;br /&gt;
&lt;br /&gt;
2) Если вы создаете inline функцию, то ее нужно размещать в header'e, так как&lt;br /&gt;
* определение функции должно быть видно из того места в коде, где она используется;&lt;br /&gt;
* если разделить определение и тело inline функции, то ее можно будет использовать только в том cpp файле, в котором находится ее тело.&lt;br /&gt;
&lt;br /&gt;
Если определить метод внутри класса, то он автоматически становится inline:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class T {&lt;br /&gt;
    int size_;&lt;br /&gt;
public:&lt;br /&gt;
    size_t getSize() const { // inline!&lt;br /&gt;
        return size_;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Шаблонные функции - тоже inline, по очевидной причине: шаблонная функция должна быть определена к моменту вызова (при инстанциировании).&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;
    void swap (T &amp;amp; a, T &amp;amp; b) {&lt;br /&gt;
        ...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Глобальные переменные==&lt;br /&gt;
Что мы о них знаем? Что их не нужно использовать :), так как невозможно спрогнозировать, что лежит в этой переменной.&lt;br /&gt;
Если у нас все же есть глобальная переменная и она определена в нескольких cpp файлах, то наша программа упадет при линковке. Избежать этого позволяет ключевое слово '''extern''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
int i = 0;&lt;br /&gt;
&lt;br /&gt;
// 2.cpp&lt;br /&gt;
extern int i;    // extern указывает на то, что i определена где-то снаружи&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На самом деле, перед любым объявлением функции автоматически ставится extern (можно явно писать, ошибки не будет).&lt;br /&gt;
&lt;br /&gt;
==Статические переменные==&lt;br /&gt;
Если уж очень нужны глобальные переменные, лучше использовать статические переменные. Ключевое слово '''static''' обеспечивает защиту от перекрытия имен. Static может использоваться в 5 контекстах:&lt;br /&gt;
&lt;br /&gt;
'''1. Статические глобальные переменные'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
static int i = 0;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Такое объявление переменной делает ее глобальной в пределах одного cpp файла, в данном случае - 1.cpp.&lt;br /&gt;
Если объявить статическую переменную i в заголовочном файле, то в каждом файле, в который будет подключен этот header, будет по одной собственной i.&lt;br /&gt;
&lt;br /&gt;
''Замечание: типы линковки.''&lt;br /&gt;
&lt;br /&gt;
Линковка бывает:&lt;br /&gt;
* external - функции и переменные между модулями;&lt;br /&gt;
* internal - внутри одного модуля. Пример использования - счетчик открытых файлов.&lt;br /&gt;
 &lt;br /&gt;
'''2. Статические функции'''&lt;br /&gt;
&lt;br /&gt;
Внутренняя линковка (internal). &lt;br /&gt;
&lt;br /&gt;
Можно создавать разные функции с одинаковыми сигнатурами. Так как они определяются во время вызова, то могут и встроиться :).&lt;br /&gt;
&lt;br /&gt;
Пример: можно в каждом cpp файле создать свою функцию static void test(). Напомню, что ключевое слово static защищает от перекрытия имен.&lt;br /&gt;
&lt;br /&gt;
'''3. Статические локальные переменные'''&lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void print (double x) {&lt;br /&gt;
    static int i = 0;&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; (++i) &amp;lt;&amp;lt; x &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Переменная i хранится не хранится на стеке. По сути, она является глобальной переменной, но ее областью видимости является только функция print.&lt;br /&gt;
&lt;br /&gt;
Статические локальные переменные уничтожаются при выходе из main().&lt;br /&gt;
&lt;br /&gt;
Если сделать функцию print статической и вставить в несколько cpp файлов, то у каждого print будет свой счетчик i и своя реализация. А если сделать ее inline, то 1 общая реализация.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим еще один пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
1. void print (char const * fn, double x) {&lt;br /&gt;
2.     static int i = 0;&lt;br /&gt;
3.     static ofstream file(fn) = q(); // q() - некоторая функция&lt;br /&gt;
4.     file &amp;lt;&amp;lt; (++i) &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;
5. }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Если бы переменная ofstream file не была статической, то при каждом входе в print файл открывался бы заново.&lt;br /&gt;
* Т.к. file - статическая, то при каждом входе в print, кроме первого раза, строка 3 игнорируется: как инициализация переменной file, так и =q(). &lt;br /&gt;
&lt;br /&gt;
Применение: храниение локальных данных функций.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
char * g() {&lt;br /&gt;
    static char m[100];&lt;br /&gt;
    return m; // имеет смысл, т.к. m static =&amp;gt; хранится не на стеке&lt;br /&gt;
}&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;
string &amp;amp; g() {&lt;br /&gt;
    static string s;&lt;br /&gt;
    return s;&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;
'''4. Статические члены данных класса '''&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;
class Array {&lt;br /&gt;
private:&lt;br /&gt;
    static int count_;   // объявление статического члена данных класса. Он не хранится в объекте класса.&lt;br /&gt;
    static string name_; // Статические члены данных класса подобны глобальным переменным внутри класса. &lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В данном примере статические члены данных объявлены private, поэтому изменять их можно только из внутренних методов класса или &amp;quot;друзьями&amp;quot; (friend).&lt;br /&gt;
Для того, чтобы проинициализировать статические члены данных, их нужно определить в каком-нибудь срр-файле, чтобы выделилась память:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Array::count_ = 0;&lt;br /&gt;
string Array::name_(&amp;quot;Array&amp;quot;);&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;
static int const dimension = 10;&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;
'''5. Статические методы класса'''&lt;br /&gt;
&lt;br /&gt;
Не зависят от объектов класса. Рассмотрим пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class Array {&lt;br /&gt;
private:&lt;br /&gt;
     static string name_;&lt;br /&gt;
public:&lt;br /&gt;
     static string getName() { // rem. getName() - inline, т.к. определена внутри класса &lt;br /&gt;
         return name_;&lt;br /&gt;
     }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    Array a;&lt;br /&gt;
    a.getName();      // cинтаксически возможно, но логически неправильно&lt;br /&gt;
&lt;br /&gt;
    Array::getName(); // правильно&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод getName() не имеет доступа к членам класса, но если передать в нее ссылку на объект класса, то из getName() можно будет изменять private поля.&lt;br /&gt;
&lt;br /&gt;
Невозможно объявить статический метод класса константным, так как const запрещает изменять поля объекта, а в static методы this не передается:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void f() const; // ошибка!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''template и static'''&lt;br /&gt;
&lt;br /&gt;
* Поведение статических локальных переменных в шаблонах функций: для каждого инстанса функции будет своя статическая локальная переменная.&lt;br /&gt;
* Static в шаблонах классов:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
template &amp;lt;class T&amp;gt; &lt;br /&gt;
    class Array {};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Для каждого инстанса класса будут свои статические поля и методы. &lt;br /&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;
// array.h&lt;br /&gt;
template &amp;lt;class T&amp;gt;&lt;br /&gt;
    class Array &lt;br /&gt;
{&lt;br /&gt;
    static double q;&lt;br /&gt;
public:&lt;br /&gt;
    Array();&lt;br /&gt;
    static double getQ() { &lt;br /&gt;
        return q;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
template &amp;lt;class T&amp;gt;&lt;br /&gt;
    double Array&amp;lt;T&amp;gt;::q = 1.5;&lt;br /&gt;
&lt;br /&gt;
// main.cpp&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;quot;array.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; Array&amp;lt;int&amp;gt;::getQ() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; Array&amp;lt;float&amp;gt;::getQ() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//output: 1.5, 1.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2 вариант:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// array.h&lt;br /&gt;
template &amp;lt;class T&amp;gt;&lt;br /&gt;
    class Array &lt;br /&gt;
{&lt;br /&gt;
    static double q;&lt;br /&gt;
public:&lt;br /&gt;
    Array();&lt;br /&gt;
    static double getQ() { &lt;br /&gt;
        return q;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
//array.cpp&lt;br /&gt;
#include &amp;quot;array.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
template &amp;lt;&amp;gt;&lt;br /&gt;
        double Array&amp;lt;int&amp;gt;::q = 1.5;&lt;br /&gt;
template &amp;lt;&amp;gt;&lt;br /&gt;
        double Array&amp;lt;float&amp;gt;::q = 2.6;&lt;br /&gt;
&lt;br /&gt;
// main.cpp&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;quot;array.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; Array&amp;lt;int&amp;gt;::getQ() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; Array&amp;lt;float&amp;gt;::getQ() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// output: 1.5, 2.6&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rem. Вообще, шаблоны не очень дружат со static параметром шаблона: не может быть указателя на статическую функцию.&lt;br /&gt;
&lt;br /&gt;
==Синглтон==&lt;br /&gt;
&lt;br /&gt;
def. Синглтон - это объект, который в момент исполнения существует в единственном экземпляре.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// array.h&lt;br /&gt;
struct Array {&lt;br /&gt;
private:&lt;br /&gt;
    // все конструкторы&lt;br /&gt;
    static Array * inst_;&lt;br /&gt;
public:&lt;br /&gt;
    static Array &amp;amp; getInstance() {&lt;br /&gt;
        if (inst_ == 0)&lt;br /&gt;
            inst_ = new Array();&lt;br /&gt;
        return *inst_;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// array.cpp&lt;br /&gt;
Array * Array::inst_ = 0;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=200</id>
		<title>Напоминание про inline и static. Синглтон.</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=200"/>
				<updated>2011-05-02T09:48:34Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Статические переменные */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Inline==&lt;br /&gt;
Рассмотрим некоторую inline функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
inline void f() {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Где ее разместить: в cpp или в header'e?'''&lt;br /&gt;
&lt;br /&gt;
1) При размещении любой функции в заголовочном файле, если данный header включен в несколько файлов вашего проекта, проект упадет при линковке, если ваша функция не inline.&lt;br /&gt;
&lt;br /&gt;
2) Если вы создаете inline функцию, то ее нужно размещать в header'e, так как&lt;br /&gt;
* определение функции должно быть видно из того места в коде, где она используется;&lt;br /&gt;
* если разделить определение и тело inline функции, то ее можно будет использовать только в том cpp файле, в котором находится ее тело.&lt;br /&gt;
&lt;br /&gt;
Если определить метод внутри класса, то он автоматически становится inline:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class T {&lt;br /&gt;
    int size_;&lt;br /&gt;
public:&lt;br /&gt;
    size_t getSize() const { // inline!&lt;br /&gt;
        return size_;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Шаблонные функции - тоже inline, по очевидной причине: шаблонная функция должна быть определена к моменту вызова (при инстанциировании).&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;
    void swap (T &amp;amp; a, T &amp;amp; b) {&lt;br /&gt;
        ...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Глобальные переменные==&lt;br /&gt;
Что мы о них знаем? Что их не нужно использовать :), так как невозможно спрогнозировать, что лежит в этой переменной.&lt;br /&gt;
Если у нас все же есть глобальная переменная и она определена в нескольких cpp файлах, то наша программа упадет при линковке. Избежать этого позволяет ключевое слово '''extern''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
int i = 0;&lt;br /&gt;
&lt;br /&gt;
// 2.cpp&lt;br /&gt;
extern int i;    // extern указывает на то, что i определена где-то снаружи&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На самом деле, перед любым объявлением функции автоматически ставится extern (можно явно писать, ошибки не будет).&lt;br /&gt;
&lt;br /&gt;
==Статические переменные==&lt;br /&gt;
Если уж очень нужны глобальные переменные, лучше использовать статические переменные. Ключевое слово '''static''' обеспечивает защиту от перекрытия имен. Static может использоваться в 5 контекстах:&lt;br /&gt;
&lt;br /&gt;
'''1. Статические глобальные переменные'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
static int i = 0;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Такое объявление переменной делает ее глобальной в пределах одного cpp файла, в данном случае - 1.cpp.&lt;br /&gt;
Если объявить статическую переменную i в заголовочном файле, то в каждом файле, в который будет подключен этот header, будет по одной собственной i.&lt;br /&gt;
&lt;br /&gt;
''Замечание: типы линковки.''&lt;br /&gt;
&lt;br /&gt;
Линковка бывает:&lt;br /&gt;
* external - функции и переменные между модулями;&lt;br /&gt;
* internal - внутри одного модуля. Пример использования - счетчик открытых файлов.&lt;br /&gt;
 &lt;br /&gt;
'''2. Статические функции'''&lt;br /&gt;
&lt;br /&gt;
Внутренняя линковка (internal). &lt;br /&gt;
&lt;br /&gt;
Можно создавать разные функции с одинаковыми сигнатурами. Так как они определяются во время вызова, то могут и встроиться :).&lt;br /&gt;
&lt;br /&gt;
Пример: можно в каждом cpp файле создать свою функцию static void test(). Напомню, что ключевое слово static защищает от перекрытия имен.&lt;br /&gt;
&lt;br /&gt;
'''3. Статические локальные переменные'''&lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void print (double x) {&lt;br /&gt;
    static int i = 0;&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; (++i) &amp;lt;&amp;lt; x &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Переменная i хранится не хранится на стеке. По сути, она является глобальной переменной, но ее областью видимости является только функция print.&lt;br /&gt;
&lt;br /&gt;
Статические локальные переменные уничтожаются при выходе из main().&lt;br /&gt;
&lt;br /&gt;
Если сделать функцию print статической и вставить в несколько cpp файлов, то у каждого print будет свой счетчик i и своя реализация. А если сделать ее inline, то 1 общая реализация.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим еще один пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
1. void print (char const * fn, double x) {&lt;br /&gt;
2.     static int i = 0;&lt;br /&gt;
3.     static ofstream file(fn) = q(); // q() - некоторая функция&lt;br /&gt;
4.     file &amp;lt;&amp;lt; (++i) &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;
5. }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Если бы переменная ofstream file не была статической, то при каждом входе в print файл открывался бы заново.&lt;br /&gt;
* Т.к. file - статическая, то при каждом входе в print, кроме первого раза, строка 3 игнорируется: как инициализация переменной file, так и =q(). &lt;br /&gt;
&lt;br /&gt;
Применение: храниение локальных данных функций.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
char * g() {&lt;br /&gt;
    static char m[100];&lt;br /&gt;
    return m; // имеет смысл, т.к. m static =&amp;gt; хранится не на стеке&lt;br /&gt;
}&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;
string &amp;amp; g() {&lt;br /&gt;
    static string s;&lt;br /&gt;
    return s;&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;
'''4. Статические члены данных класса '''&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;
class Array {&lt;br /&gt;
private:&lt;br /&gt;
    static int count_;   // объявление статического члена данных класса. Он не хранится в объекте класса.&lt;br /&gt;
    static string name_; // Статические члены данных класса подобны глобальным переменным внутри класса. &lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В данном примере статические члены данных объявлены private, поэтому изменять их можно только из внутренних методов класса или &amp;quot;друзьями&amp;quot; (friend).&lt;br /&gt;
Для того, чтобы проинициализировать статические члены данных, их нужно определить в каком-нибудь срр-файле, чтобы выделилась память:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Array::count_ = 0;&lt;br /&gt;
string Array::name_(&amp;quot;Array&amp;quot;);&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;
static int const dimension = 10;&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;
'''5. Статические методы класса'''&lt;br /&gt;
&lt;br /&gt;
Не зависят от объектов класса. Рассмотрим пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class Array {&lt;br /&gt;
private:&lt;br /&gt;
     static string name_;&lt;br /&gt;
public:&lt;br /&gt;
     static string getName() { // rem. getName() - inline, т.к. определена внутри класса &lt;br /&gt;
         return name_;&lt;br /&gt;
     }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    Array a;&lt;br /&gt;
    a.getName();      // cинтаксически возможно, но логически неправильно&lt;br /&gt;
&lt;br /&gt;
    Array::getName(); // правильно&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод getName() не имеет доступа к членам класса, но если передать в нее ссылку на объект класса, то из getName() можно будет изменять private поля.&lt;br /&gt;
&lt;br /&gt;
Невозможно объявить статический метод класса константным, так как const запрещает изменять поля объекта, а в static методы this не передается:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
static void f() const; // ошибка!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''template и static'''&lt;br /&gt;
&lt;br /&gt;
* Поведение статических локальных переменных в шаблонах функций: для каждого инстанса функции будет своя статическая локальная переменная.&lt;br /&gt;
* Static в шаблонах классов:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
template &amp;lt;class T&amp;gt; &lt;br /&gt;
    class Array {};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Для каждого инстанса класса будут свои статические поля и методы. &lt;br /&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;
// array.h&lt;br /&gt;
template &amp;lt;class T&amp;gt;&lt;br /&gt;
    class Array &lt;br /&gt;
{&lt;br /&gt;
    static double q;&lt;br /&gt;
public:&lt;br /&gt;
    Array();&lt;br /&gt;
    static double getQ() { &lt;br /&gt;
        return q;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
template &amp;lt;class T&amp;gt;&lt;br /&gt;
    double Array&amp;lt;T&amp;gt;::q = 1.5;&lt;br /&gt;
&lt;br /&gt;
// main.cpp&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;quot;array.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; Array&amp;lt;int&amp;gt;::getQ() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; Array&amp;lt;float&amp;gt;::getQ() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//output: 1.5, 1.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2 вариант:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// array.h&lt;br /&gt;
template &amp;lt;class T&amp;gt;&lt;br /&gt;
    class Array &lt;br /&gt;
{&lt;br /&gt;
    static double q;&lt;br /&gt;
public:&lt;br /&gt;
    Array();&lt;br /&gt;
    static double getQ() { &lt;br /&gt;
        return q;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
//array.cpp&lt;br /&gt;
#include &amp;quot;array.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
template &amp;lt;&amp;gt;&lt;br /&gt;
        double Array&amp;lt;int&amp;gt;::q = 1.5;&lt;br /&gt;
template &amp;lt;&amp;gt;&lt;br /&gt;
        double Array&amp;lt;float&amp;gt;::q = 2.6;&lt;br /&gt;
&lt;br /&gt;
// main.cpp&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;quot;array.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; Array&amp;lt;int&amp;gt;::getQ() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; Array&amp;lt;float&amp;gt;::getQ() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// output: 1.5, 2.6&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rem. Вообще, шаблоны не очень дружат со static параметром шаблона: не может быть указателя на статическую функцию.&lt;br /&gt;
&lt;br /&gt;
==Синглтон==&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=199</id>
		<title>Напоминание про inline и static. Синглтон.</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=199"/>
				<updated>2011-05-02T08:19:31Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Inline */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Inline==&lt;br /&gt;
Рассмотрим некоторую inline функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
inline void f() {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Где ее разместить: в cpp или в header'e?'''&lt;br /&gt;
&lt;br /&gt;
1) При размещении любой функции в заголовочном файле, если данный header включен в несколько файлов вашего проекта, проект упадет при линковке, если ваша функция не inline.&lt;br /&gt;
&lt;br /&gt;
2) Если вы создаете inline функцию, то ее нужно размещать в header'e, так как&lt;br /&gt;
* определение функции должно быть видно из того места в коде, где она используется;&lt;br /&gt;
* если разделить определение и тело inline функции, то ее можно будет использовать только в том cpp файле, в котором находится ее тело.&lt;br /&gt;
&lt;br /&gt;
Если определить метод внутри класса, то он автоматически становится inline:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class T {&lt;br /&gt;
    int size_;&lt;br /&gt;
public:&lt;br /&gt;
    size_t getSize() const { // inline!&lt;br /&gt;
        return size_;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Шаблонные функции - тоже inline, по очевидной причине: шаблонная функция должна быть определена к моменту вызова (при инстанциировании).&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;
    void swap (T &amp;amp; a, T &amp;amp; b) {&lt;br /&gt;
        ...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Глобальные переменные==&lt;br /&gt;
Что мы о них знаем? Что их не нужно использовать :), так как невозможно спрогнозировать, что лежит в этой переменной.&lt;br /&gt;
Если у нас все же есть глобальная переменная и она определена в нескольких cpp файлах, то наша программа упадет при линковке. Избежать этого позволяет ключевое слово '''extern''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
int i = 0;&lt;br /&gt;
&lt;br /&gt;
// 2.cpp&lt;br /&gt;
extern int i;    // extern указывает на то, что i определена где-то снаружи&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На самом деле, перед любым объявлением функции автоматически ставится extern (можно явно писать, ошибки не будет).&lt;br /&gt;
&lt;br /&gt;
==Статические переменные==&lt;br /&gt;
Если уж очень нужны глобальные переменные, лучше использовать статические переменные. Ключевое слово '''static''' обеспечивает защиту от перекрытия имен. Static может использоваться в 5 контекстах:&lt;br /&gt;
'''1. Статические глобальные переменные'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
static int i = 0;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Такое объявление переменной делает ее глобальной в пределах одного cpp файла, в данном случае - 1.cpp.&lt;br /&gt;
Если объявить статическую переменную i в заголовочном файле, то в каждом файле, в который будет подключен этот header, будет по одной собственной i.&lt;br /&gt;
&lt;br /&gt;
''Замечание: типы линковки.''&lt;br /&gt;
Линковка бывает:&lt;br /&gt;
* external - функции и переменные между модулями;&lt;br /&gt;
* internal - внутри одного модуля. Пример использования - счетчик открытых файлов.&lt;br /&gt;
 &lt;br /&gt;
'''2. Статические функции'''&lt;br /&gt;
Внутренняя линковка (internal). &lt;br /&gt;
Можно создавать разные функции с одинаковыми сигнатурами. Так как они определяются во время вызова, то могут и встроиться :).&lt;br /&gt;
Пример: можно в каждом cpp файле создать свою функцию static void test(). Напомню, что ключевое слово static защищает от перекрытия имен.&lt;br /&gt;
&lt;br /&gt;
'''3. Статические локальные переменные'''&lt;br /&gt;
Рассмотрим следующую функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void print (double x) {&lt;br /&gt;
    static int i = 0;&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; (++i) &amp;lt;&amp;lt; x &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Переменная i хранится не хранится на стеке (А ГДЕ?). По сути, она является глобальной переменной, но ее областью видимости является только функция print.&lt;br /&gt;
&lt;br /&gt;
Если сделать функцию print статической и вставить в несколько cpp файлов, то у каждого print будет свой счетчик i и своя реализация. А если сделать ее inline, то 1 общая реализация.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим еще один пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void print (char const * fn, double x) {&lt;br /&gt;
    static int i = 0;&lt;br /&gt;
    static ofstream file(fn) = q(); // q() - некоторая функция&lt;br /&gt;
    file &amp;lt;&amp;lt; (++i) &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;
}&lt;br /&gt;
* Если бы переменная ofstream file не была статической, то при каждом входе в print файл открывался бы заново.&lt;br /&gt;
* Т.к. file - статическая, то при каждом входе в print &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''4. Статические члены класса'''&lt;br /&gt;
'''5. Статические методы класса'''&lt;br /&gt;
&lt;br /&gt;
==Синглтон==&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=198</id>
		<title>Напоминание про inline и static. Синглтон.</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=198"/>
				<updated>2011-04-23T10:00:09Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Статические переменные */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Inline==&lt;br /&gt;
Рассмотрим некоторую inline функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
inline void f() {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Где ее разместить: в cpp или в header'e?'''&lt;br /&gt;
&lt;br /&gt;
1) При размещении любой функции в заголовочном файле, если данный header включен в несколько файлов вашего проекта, проект упадет при линковке, если ваша функция не inline.&lt;br /&gt;
&lt;br /&gt;
2) Ключевое слово inline обязывает программиста размещать такую функцию в header'e, так как&lt;br /&gt;
* определение функции должно быть видно из того места в коде, где она используется;&lt;br /&gt;
* если разделить определение и тело inline функции, то ее можно будет использовать только в том cpp файле, в котором находится ее тело.&lt;br /&gt;
&lt;br /&gt;
Если определить метод внутри класса, то он автоматически становится inline:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class T {&lt;br /&gt;
    int size_;&lt;br /&gt;
public:&lt;br /&gt;
    size_t getSize() const { // inline!&lt;br /&gt;
        return size_;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Шаблонные функции - тоже inline, по очевидной причине: шаблонная функция должна быть определена к моменту вызова (при инстанциировании).&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;
    void swap (T &amp;amp; a, T &amp;amp; b) {&lt;br /&gt;
        ...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Глобальные переменные==&lt;br /&gt;
Что мы о них знаем? Что их не нужно использовать :), так как невозможно спрогнозировать, что лежит в этой переменной.&lt;br /&gt;
Если у нас все же есть глобальная переменная и она определена в нескольких cpp файлах, то наша программа упадет при линковке. Избежать этого позволяет ключевое слово '''extern''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
int i = 0;&lt;br /&gt;
&lt;br /&gt;
// 2.cpp&lt;br /&gt;
extern int i;    // extern указывает на то, что i определена где-то снаружи&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На самом деле, перед любым объявлением функции автоматически ставится extern (можно явно писать, ошибки не будет).&lt;br /&gt;
&lt;br /&gt;
==Статические переменные==&lt;br /&gt;
Если уж очень нужны глобальные переменные, лучше использовать статические переменные. Ключевое слово '''static''' обеспечивает защиту от перекрытия имен. Static может использоваться в 5 контекстах:&lt;br /&gt;
'''1. Статические глобальные переменные'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
static int i = 0;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Такое объявление переменной делает ее глобальной в пределах одного cpp файла, в данном случае - 1.cpp.&lt;br /&gt;
Если объявить статическую переменную i в заголовочном файле, то в каждом файле, в который будет подключен этот header, будет по одной собственной i.&lt;br /&gt;
&lt;br /&gt;
''Замечание: типы линковки.''&lt;br /&gt;
Линковка бывает:&lt;br /&gt;
* external - функции и переменные между модулями;&lt;br /&gt;
* internal - внутри одного модуля. Пример использования - счетчик открытых файлов.&lt;br /&gt;
 &lt;br /&gt;
'''2. Статические функции'''&lt;br /&gt;
Внутренняя линковка (internal). &lt;br /&gt;
Можно создавать разные функции с одинаковыми сигнатурами. Так как они определяются во время вызова, то могут и встроиться :).&lt;br /&gt;
Пример: можно в каждом cpp файле создать свою функцию static void test(). Напомню, что ключевое слово static защищает от перекрытия имен.&lt;br /&gt;
&lt;br /&gt;
'''3. Статические локальные переменные'''&lt;br /&gt;
Рассмотрим следующую функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void print (double x) {&lt;br /&gt;
    static int i = 0;&lt;br /&gt;
    std::cout &amp;lt;&amp;lt; (++i) &amp;lt;&amp;lt; x &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Переменная i хранится не хранится на стеке (А ГДЕ?). По сути, она является глобальной переменной, но ее областью видимости является только функция print.&lt;br /&gt;
&lt;br /&gt;
Если сделать функцию print статической и вставить в несколько cpp файлов, то у каждого print будет свой счетчик i и своя реализация. А если сделать ее inline, то 1 общая реализация.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим еще один пример:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void print (char const * fn, double x) {&lt;br /&gt;
    static int i = 0;&lt;br /&gt;
    static ofstream file(fn) = q(); // q() - некоторая функция&lt;br /&gt;
    file &amp;lt;&amp;lt; (++i) &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;
}&lt;br /&gt;
* Если бы переменная ofstream file не была статической, то при каждом входе в print файл открывался бы заново.&lt;br /&gt;
* Т.к. file - статическая, то при каждом входе в print &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''4. Статические члены класса'''&lt;br /&gt;
'''5. Статические методы класса'''&lt;br /&gt;
&lt;br /&gt;
==Синглтон==&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=196</id>
		<title>Напоминание про inline и static. Синглтон.</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=196"/>
				<updated>2011-04-23T09:35:30Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Inline */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Inline==&lt;br /&gt;
Рассмотрим некоторую inline функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
inline void f() {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Где ее разместить: в cpp или в header'e?'''&lt;br /&gt;
&lt;br /&gt;
1) При размещении любой функции в заголовочном файле, если данный header включен в несколько файлов вашего проекта, проект упадет при линковке, если ваша функция не inline.&lt;br /&gt;
&lt;br /&gt;
2) Ключевое слово inline обязывает программиста размещать такую функцию в header'e, так как&lt;br /&gt;
* определение функции должно быть видно из того места в коде, где она используется;&lt;br /&gt;
* если разделить определение и тело inline функции, то ее можно будет использовать только в том cpp файле, в котором находится ее тело.&lt;br /&gt;
&lt;br /&gt;
Если определить метод внутри класса, то он автоматически становится inline:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class T {&lt;br /&gt;
    int size_;&lt;br /&gt;
public:&lt;br /&gt;
    size_t getSize() const { // inline!&lt;br /&gt;
        return size_;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Шаблонные функции - тоже inline, по очевидной причине: шаблонная функция должна быть определена к моменту вызова (при инстанциировании).&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;
    void swap (T &amp;amp; a, T &amp;amp; b) {&lt;br /&gt;
        ...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Глобальные переменные==&lt;br /&gt;
Что мы о них знаем? Что их не нужно использовать :), так как невозможно спрогнозировать, что лежит в этой переменной.&lt;br /&gt;
Если у нас все же есть глобальная переменная и она определена в нескольких cpp файлах, то наша программа упадет при линковке. Избежать этого позволяет ключевое слово '''extern''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
int i = 0;&lt;br /&gt;
&lt;br /&gt;
// 2.cpp&lt;br /&gt;
extern int i;    // extern указывает на то, что i определена где-то снаружи&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На самом деле, перед любым объявлением функции автоматически ставится extern (можно явно писать, ошибки не будет).&lt;br /&gt;
&lt;br /&gt;
==Статические переменные==&lt;br /&gt;
Если уж очень нужны глобальные переменные, лучше использовать статические переменные. Ключевое слово '''static''' обеспечивает защиту от перекрытия имен. Static может использоваться в 5 контекстах:&lt;br /&gt;
===1. Статические глобальные переменные===&lt;br /&gt;
===2. Статические функции===&lt;br /&gt;
===3. Статические локальные переменные===&lt;br /&gt;
===4. Статические члены класса===&lt;br /&gt;
===5. Статические методы класса===&lt;br /&gt;
&lt;br /&gt;
==Синглтон==&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=195</id>
		<title>Напоминание про inline и static. Синглтон.</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=195"/>
				<updated>2011-04-23T09:34:59Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Inline */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Inline==&lt;br /&gt;
Рассмотрим некоторую inline функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
inline void f() {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Где ее разместить: в cpp или в header'e?'''&lt;br /&gt;
 1) При размещении любой функции в заголовочном файле, если данный header включен в несколько файлов вашего проекта, проект упадет при линковке, если ваша функция не inline.&lt;br /&gt;
 2) Ключевое слово inline обязывает программиста размещать такую функцию в header'e, так как&lt;br /&gt;
* определение функции должно быть видно из того места в коде, где она используется;&lt;br /&gt;
* если разделить определение и тело inline функции, то ее можно будет использовать только в том cpp файле, в котором находится ее тело.&lt;br /&gt;
&lt;br /&gt;
Если определить метод внутри класса, то он автоматически становится inline:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class T {&lt;br /&gt;
    int size_;&lt;br /&gt;
public:&lt;br /&gt;
    size_t getSize() const { // inline!&lt;br /&gt;
        return size_;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Шаблонные функции - тоже inline, по очевидной причине: шаблонная функция должна быть определена к моменту вызова (при инстанциировании).&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;
    void swap (T &amp;amp; a, T &amp;amp; b) {&lt;br /&gt;
        ...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Глобальные переменные==&lt;br /&gt;
Что мы о них знаем? Что их не нужно использовать :), так как невозможно спрогнозировать, что лежит в этой переменной.&lt;br /&gt;
Если у нас все же есть глобальная переменная и она определена в нескольких cpp файлах, то наша программа упадет при линковке. Избежать этого позволяет ключевое слово '''extern''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
int i = 0;&lt;br /&gt;
&lt;br /&gt;
// 2.cpp&lt;br /&gt;
extern int i;    // extern указывает на то, что i определена где-то снаружи&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На самом деле, перед любым объявлением функции автоматически ставится extern (можно явно писать, ошибки не будет).&lt;br /&gt;
&lt;br /&gt;
==Статические переменные==&lt;br /&gt;
Если уж очень нужны глобальные переменные, лучше использовать статические переменные. Ключевое слово '''static''' обеспечивает защиту от перекрытия имен. Static может использоваться в 5 контекстах:&lt;br /&gt;
===1. Статические глобальные переменные===&lt;br /&gt;
===2. Статические функции===&lt;br /&gt;
===3. Статические локальные переменные===&lt;br /&gt;
===4. Статические члены класса===&lt;br /&gt;
===5. Статические методы класса===&lt;br /&gt;
&lt;br /&gt;
==Синглтон==&lt;/div&gt;</summary>
		<author><name>Katepol</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=194</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=194"/>
				<updated>2011-04-23T09:28:08Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Конспекты по C++&lt;br /&gt;
1 семестр (осень-зима 2010)&lt;br /&gt;
* [[ Как происходит компиляция|Как происходит компиляция. Алексей Давыдов. 08.09.2010]]&lt;br /&gt;
* [[ Указатели и ссылки|Указатели и ссылки. Екатерина Полищук. 10.09.2010]]&lt;br /&gt;
* [[ Динамическое распределение памяти|Динамическое распределение памяти. Алексей Гуревич. 17.09.2010]]&lt;br /&gt;
* [[ Перегрузка операторов|Перегрузка операторов. Мария Фомкина. 12.11.2010]]&lt;br /&gt;
&lt;br /&gt;
2 семестр (зима-весна 2011)&lt;br /&gt;
* [[ Напоминание про inline и static. Синглтон.|Напоминание про inline и static. Синглтон. Екатерина Полищук. 11.02.2011]]&lt;br /&gt;
* [[ STL. Последовательные контейнеры|STL. Последовательные контейнеры. Мария Фомкина. 18.02.2011]]&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=192</id>
		<title>Напоминание про inline и static. Синглтон.</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=192"/>
				<updated>2011-04-23T09:26:17Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: переименовал «Напоминание про inline и static» в «Напоминание про inline и static. Синглтон.»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Inline==&lt;br /&gt;
Рассмотрим некоторую inline функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
inline void f() {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Где ее разместить: в cpp или в header'e?'''&lt;br /&gt;
1) При размещении любой функции в заголовочном файле, если данный header включен в несколько файлов вашего проекта, проект упадет при линковке, если ваша функция не inline.&lt;br /&gt;
2) Ключевое слово inline обязывает программиста размещать такую функцию в header'e, так как&lt;br /&gt;
 * определение функции должно быть видно из того места в коде, где она используется;&lt;br /&gt;
 * если разделить определение и тело inline функции, то ее можно будет использовать только в том cpp файле, в котором находится ее тело.&lt;br /&gt;
&lt;br /&gt;
Если определить метод внутри класса, то он автоматически становится inline:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class T {&lt;br /&gt;
    int size_;&lt;br /&gt;
public:&lt;br /&gt;
    size_t getSize() const { // inline!&lt;br /&gt;
        return size_;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Шаблонные функции - тоже inline, по очевидной причине: шаблонная функция должна быть определена к моменту вызова (при инстанциировании).&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;
    void swap (T &amp;amp; a, T &amp;amp; b) {&lt;br /&gt;
        ...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
==Глобальные переменные==&lt;br /&gt;
Что мы о них знаем? Что их не нужно использовать :), так как невозможно спрогнозировать, что лежит в этой переменной.&lt;br /&gt;
Если у нас все же есть глобальная переменная и она определена в нескольких cpp файлах, то наша программа упадет при линковке. Избежать этого позволяет ключевое слово '''extern''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
int i = 0;&lt;br /&gt;
&lt;br /&gt;
// 2.cpp&lt;br /&gt;
extern int i;    // extern указывает на то, что i определена где-то снаружи&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На самом деле, перед любым объявлением функции автоматически ставится extern (можно явно писать, ошибки не будет).&lt;br /&gt;
&lt;br /&gt;
==Статические переменные==&lt;br /&gt;
Если уж очень нужны глобальные переменные, лучше использовать статические переменные. Ключевое слово '''static''' обеспечивает защиту от перекрытия имен. Static может использоваться в 5 контекстах:&lt;br /&gt;
===1. Статические глобальные переменные===&lt;br /&gt;
===2. Статические функции===&lt;br /&gt;
===3. Статические локальные переменные===&lt;br /&gt;
===4. Статические члены класса===&lt;br /&gt;
===5. Статические методы класса===&lt;br /&gt;
&lt;br /&gt;
==Синглтон==&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static&amp;diff=193</id>
		<title>Напоминание про inline и static</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static&amp;diff=193"/>
				<updated>2011-04-23T09:26:17Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: переименовал «Напоминание про inline и static» в «Напоминание про inline и static. Синглтон.»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#перенаправление [[Напоминание про inline и static. Синглтон.]]&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=191</id>
		<title>Напоминание про inline и static. Синглтон.</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%9D%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE_inline_%D0%B8_static._%D0%A1%D0%B8%D0%BD%D0%B3%D0%BB%D1%82%D0%BE%D0%BD.&amp;diff=191"/>
				<updated>2011-04-23T09:25:30Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: Новая страница: «==Inline== Рассмотрим некоторую inline функцию: &amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt; inline void f() {} &amp;lt;/source&amp;gt; '''Где ее разместить: в cp…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Inline==&lt;br /&gt;
Рассмотрим некоторую inline функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
inline void f() {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Где ее разместить: в cpp или в header'e?'''&lt;br /&gt;
1) При размещении любой функции в заголовочном файле, если данный header включен в несколько файлов вашего проекта, проект упадет при линковке, если ваша функция не inline.&lt;br /&gt;
2) Ключевое слово inline обязывает программиста размещать такую функцию в header'e, так как&lt;br /&gt;
 * определение функции должно быть видно из того места в коде, где она используется;&lt;br /&gt;
 * если разделить определение и тело inline функции, то ее можно будет использовать только в том cpp файле, в котором находится ее тело.&lt;br /&gt;
&lt;br /&gt;
Если определить метод внутри класса, то он автоматически становится inline:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class T {&lt;br /&gt;
    int size_;&lt;br /&gt;
public:&lt;br /&gt;
    size_t getSize() const { // inline!&lt;br /&gt;
        return size_;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Шаблонные функции - тоже inline, по очевидной причине: шаблонная функция должна быть определена к моменту вызова (при инстанциировании).&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;
    void swap (T &amp;amp; a, T &amp;amp; b) {&lt;br /&gt;
        ...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
==Глобальные переменные==&lt;br /&gt;
Что мы о них знаем? Что их не нужно использовать :), так как невозможно спрогнозировать, что лежит в этой переменной.&lt;br /&gt;
Если у нас все же есть глобальная переменная и она определена в нескольких cpp файлах, то наша программа упадет при линковке. Избежать этого позволяет ключевое слово '''extern''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1.cpp&lt;br /&gt;
int i = 0;&lt;br /&gt;
&lt;br /&gt;
// 2.cpp&lt;br /&gt;
extern int i;    // extern указывает на то, что i определена где-то снаружи&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На самом деле, перед любым объявлением функции автоматически ставится extern (можно явно писать, ошибки не будет).&lt;br /&gt;
&lt;br /&gt;
==Статические переменные==&lt;br /&gt;
Если уж очень нужны глобальные переменные, лучше использовать статические переменные. Ключевое слово '''static''' обеспечивает защиту от перекрытия имен. Static может использоваться в 5 контекстах:&lt;br /&gt;
===1. Статические глобальные переменные===&lt;br /&gt;
===2. Статические функции===&lt;br /&gt;
===3. Статические локальные переменные===&lt;br /&gt;
===4. Статические члены класса===&lt;br /&gt;
===5. Статические методы класса===&lt;br /&gt;
&lt;br /&gt;
==Синглтон==&lt;/div&gt;</summary>
		<author><name>Katepol</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=190</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=190"/>
				<updated>2011-04-23T08:56:43Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Конспекты по C++&lt;br /&gt;
1 семестр (осень-зима 2010)&lt;br /&gt;
* [[ Как происходит компиляция|Как происходит компиляция. Алексей Давыдов. 08.09.2010]]&lt;br /&gt;
* [[ Указатели и ссылки|Указатели и ссылки. Екатерина Полищук. 10.09.2010]]&lt;br /&gt;
* [[ Динамическое распределение памяти|Динамическое распределение памяти. Алексей Гуревич. 17.09.2010]]&lt;br /&gt;
* [[ Перегрузка операторов|Перегрузка операторов. Мария Фомкина. 12.11.2010]]&lt;br /&gt;
&lt;br /&gt;
2 семестр (зима-весна 2011)&lt;br /&gt;
* [[ Напоминание про inline и static|Напоминание про inline и static. Екатерина Полищук. 11.02.2011]]&lt;br /&gt;
* [[ STL. Последовательные контейнеры|STL. Последовательные контейнеры. Мария Фомкина. 18.02.2011]]&lt;/div&gt;</summary>
		<author><name>Katepol</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=189</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=189"/>
				<updated>2011-04-23T08:56:21Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Конспекты по C++&lt;br /&gt;
1 семестр (осень-зима 2010)&lt;br /&gt;
* [[ Как происходит компиляция|Как происходит компиляция. Алексей Давыдов. 08.09.2010]]&lt;br /&gt;
* [[ Указатели и ссылки|Указатели и ссылки. Екатерина Полищук. 10.09.2010]]&lt;br /&gt;
* [[ Динамическое распределение памяти|Динамическое распределение памяти. Алексей Гуревич. 17.09.2010]]&lt;br /&gt;
* [[ Перегрузка операторов|Перегрузка операторов. Мария Фомкина. 12.11.2010]]&lt;br /&gt;
&lt;br /&gt;
2 семестр (зима-весна 2011)&lt;br /&gt;
* [[ Напоминание про inline и static|Напоминание про inline и static. Екатерина Полищук. 11.02.2010]]&lt;br /&gt;
* [[ STL. Последовательные контейнеры|STL. Последовательные контейнеры. Мария Фомкина. 18.02.2011]]&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=164</id>
		<title>Указатели и ссылки</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=164"/>
				<updated>2011-03-30T08:00:49Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Указатели на указатель */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;
Пример создания указателя на int и на double:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int a=5;&lt;br /&gt;
int *pa = &amp;amp;amp;a;&lt;br /&gt;
double d = 1.5;&lt;br /&gt;
double *pd = &amp;amp;amp;d;&lt;br /&gt;
&lt;br /&gt;
pa = pd //нельзя! т.к. указатели на данные разного типа&lt;br /&gt;
&lt;br /&gt;
pa = (int*)pd; //компилируется&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя операция лишена смысла, т.к. элемент типа double занимает 8 байт, а элемент типа int - 4 байта (в х32). &lt;br /&gt;
Поэтому указатель pa будет указывать на первые 4 байта данных, расположенных по&lt;br /&gt;
адресу, хранящемуся в pd.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример функции, которая должна менять местами два значения:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int a, int b)&lt;br /&gt;
{&lt;br /&gt;
	int t = a;&lt;br /&gt;
	a = b;&lt;br /&gt;
	b = t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (k, m);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Несмотря на то, что все написано правильно, после возврата из функции swap значения k и m не изменились. Это обусловлено &lt;br /&gt;
тем, что при передаче в функцию происходит копирование параметров. Таким образом, изменились скопированные значения, &lt;br /&gt;
а исходные остались прежними. Чтобы иметь возможность менять параметры их следует передавать по указателю:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int *a, int *b)&lt;br /&gt;
{&lt;br /&gt;
	int t = *a;&lt;br /&gt;
	*a = *b;&lt;br /&gt;
	*b = *t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (&amp;amp;amp;k, &amp;amp;amp;m);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Теперь значения k и m изменились, так как при передаче в функцию произошло копирование адресов переменных, а адреса мы менять не хотели.&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 a[5] = {1, 2, 3}; //в памяти лежат 1,2,3,0,0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 _ _ _  ___________________ _ _&lt;br /&gt;
 _ _ _ |_1_|_2_|_3_|_0_|_0_|_ _&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 *p = 0; //&amp;quot;нулевой&amp;quot; указатель, nil. Означает, что он не указывает ни на какую ячейку памяти.&lt;br /&gt;
p = a; // &amp;amp;amp;a[0]&lt;br /&gt;
a = 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;
int max_element (int m[10]) {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Массив передается по ссылке (не копируется).''&lt;br /&gt;
Вызов: max_element(a);&lt;br /&gt;
Функция max_element будет работать только с массивами из 10 элементов (с другими&lt;br /&gt;
- не скомпилируется). Правильнее делать так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int max_element (int *m, int size) &lt;br /&gt;
{&lt;br /&gt;
	int max = *m; &lt;br /&gt;
	for (int i=1; i != size; ++i)&lt;br /&gt;
		if (m[i] &amp;gt;= max)&lt;br /&gt;
			max = m[i];&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, 5); &lt;br /&gt;
&lt;br /&gt;
Проблемы такой реализации:&lt;br /&gt;
* функция не работает с массивами нулевой длины;&lt;br /&gt;
* не отследить случаи выхода за границы массива.&lt;br /&gt;
&lt;br /&gt;
===Арифметика указателей===&lt;br /&gt;
Пусть q, p - указатели, а i - число. Возможные операции:&lt;br /&gt;
* p+i, p-i	сдвиг по массиву на i элементов вправо/влево&lt;br /&gt;
* p[i] &amp;amp;lt;=&amp;amp;gt; *(p+i)&lt;br /&gt;
* q-p		количество элементов массива между p и q. Разность указателей имеет тип size_t.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим две реализации функции подсчета длины символов в строке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int strlen1 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	int len=0;&lt;br /&gt;
	while (s[len]!=0)&lt;br /&gt;
		++len;&lt;br /&gt;
	return len;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int strlen2 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	char *p = s;&lt;br /&gt;
	while (*p!=0)&lt;br /&gt;
		++p;&lt;br /&gt;
	return p-s;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первая реализация более трудоемка, так как s[len] &amp;amp;lt;=&amp;amp;gt; *(s+len) то есть смещению по массиву и разименованию (2 операции), &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 foo (int *first, int *last);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Где first является указателем на первый элемент массивва (a[0]), а last указателем на область памяти сразу за массивом (&amp;quot;a[n]&amp;quot;). &lt;br /&gt;
Такой выбор указателя last обеспечивает работу с массивами нулевой длины.&lt;br /&gt;
Перепишем функцию max_element:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int* max_element (int *m, int *last)&lt;br /&gt;
{&lt;br /&gt;
	int *max = m;&lt;br /&gt;
	for (; m != last; ++m)&lt;br /&gt;
		if (*m &amp;gt;= *max)&lt;br /&gt;
			max = m;&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, a+5);&lt;br /&gt;
Следует отметить, что теперь функция max_element возвращает не значение&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 findch (char *s, char p)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
			return i;&lt;br /&gt;
	return -1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вообще данная функция должна информировать о двух вещах: во-первых, найден ли искомый символ, а во-вторых, если да, то его позицию. &lt;br /&gt;
Будет правильно возвращать 2 значения соответственно, а не совмещать все в одном. Перепишем функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool findch (char *s, char p, int *n=0)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
		{&lt;br /&gt;
			*n = i;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
	return false;&lt;br /&gt;
}&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 idx = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;idx)) {...}&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;
bool findch (char *s, char p, char **pos=0)&lt;br /&gt;
{&lt;br /&gt;
	while (*s!=0)&lt;br /&gt;
	{&lt;br /&gt;
		if (*s==p)&lt;br /&gt;
		{&lt;br /&gt;
			if (pos)&lt;br /&gt;
				*pos=s;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
		++s;&lt;br /&gt;
	}&lt;br /&gt;
	return false;&lt;br /&gt;
} &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;
char *pos = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;pos) {...}&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;
int a = 5;&lt;br /&gt;
int &amp;amp;amp;b = a; //b - ссылка на а&lt;br /&gt;
&lt;br /&gt;
b = 10; //в а тоже стало 10&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Функция swap с использованием ссылок будет выглядеть так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int &amp;amp;amp;a, int &amp;amp;amp;b)&lt;br /&gt;
{&lt;br /&gt;
	int t=b;&lt;br /&gt;
	b=a;&lt;br /&gt;
	a=t;&lt;br /&gt;
}&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 c = 30;&lt;br /&gt;
swap (a, c);&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;
* &amp;amp;amp;q	взятие адреса переменной q&lt;br /&gt;
* *pa	  	разименование&lt;br /&gt;
* int &amp;amp;amp;a	передача переменной а по ссылке&lt;br /&gt;
* int *pa   	передача переменной по адресу.&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=163</id>
		<title>Указатели и ссылки</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=163"/>
				<updated>2011-03-30T07:59:50Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Встроенные массивы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;
Пример создания указателя на int и на double:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int a=5;&lt;br /&gt;
int *pa = &amp;amp;amp;a;&lt;br /&gt;
double d = 1.5;&lt;br /&gt;
double *pd = &amp;amp;amp;d;&lt;br /&gt;
&lt;br /&gt;
pa = pd //нельзя! т.к. указатели на данные разного типа&lt;br /&gt;
&lt;br /&gt;
pa = (int*)pd; //компилируется&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя операция лишена смысла, т.к. элемент типа double занимает 8 байт, а элемент типа int - 4 байта (в х32). &lt;br /&gt;
Поэтому указатель pa будет указывать на первые 4 байта данных, расположенных по&lt;br /&gt;
адресу, хранящемуся в pd.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример функции, которая должна менять местами два значения:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int a, int b)&lt;br /&gt;
{&lt;br /&gt;
	int t = a;&lt;br /&gt;
	a = b;&lt;br /&gt;
	b = t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (k, m);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Несмотря на то, что все написано правильно, после возврата из функции swap значения k и m не изменились. Это обусловлено &lt;br /&gt;
тем, что при передаче в функцию происходит копирование параметров. Таким образом, изменились скопированные значения, &lt;br /&gt;
а исходные остались прежними. Чтобы иметь возможность менять параметры их следует передавать по указателю:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int *a, int *b)&lt;br /&gt;
{&lt;br /&gt;
	int t = *a;&lt;br /&gt;
	*a = *b;&lt;br /&gt;
	*b = *t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (&amp;amp;amp;k, &amp;amp;amp;m);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Теперь значения k и m изменились, так как при передаче в функцию произошло копирование адресов переменных, а адреса мы менять не хотели.&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 a[5] = {1, 2, 3}; //в памяти лежат 1,2,3,0,0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 _ _ _  ___________________ _ _&lt;br /&gt;
 _ _ _ |_1_|_2_|_3_|_0_|_0_|_ _&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 *p = 0; //&amp;quot;нулевой&amp;quot; указатель, nil. Означает, что он не указывает ни на какую ячейку памяти.&lt;br /&gt;
p = a; // &amp;amp;amp;a[0]&lt;br /&gt;
a = 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;
int max_element (int m[10]) {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Массив передается по ссылке (не копируется).''&lt;br /&gt;
Вызов: max_element(a);&lt;br /&gt;
Функция max_element будет работать только с массивами из 10 элементов (с другими&lt;br /&gt;
- не скомпилируется). Правильнее делать так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int max_element (int *m, int size) &lt;br /&gt;
{&lt;br /&gt;
	int max = *m; &lt;br /&gt;
	for (int i=1; i != size; ++i)&lt;br /&gt;
		if (m[i] &amp;gt;= max)&lt;br /&gt;
			max = m[i];&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, 5); &lt;br /&gt;
&lt;br /&gt;
Проблемы такой реализации:&lt;br /&gt;
* функция не работает с массивами нулевой длины;&lt;br /&gt;
* не отследить случаи выхода за границы массива.&lt;br /&gt;
&lt;br /&gt;
===Арифметика указателей===&lt;br /&gt;
Пусть q, p - указатели, а i - число. Возможные операции:&lt;br /&gt;
* p+i, p-i	сдвиг по массиву на i элементов вправо/влево&lt;br /&gt;
* p[i] &amp;amp;lt;=&amp;amp;gt; *(p+i)&lt;br /&gt;
* q-p		количество элементов массива между p и q. Разность указателей имеет тип size_t.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим две реализации функции подсчета длины символов в строке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int strlen1 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	int len=0;&lt;br /&gt;
	while (s[len]!=0)&lt;br /&gt;
		++len;&lt;br /&gt;
	return len;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int strlen2 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	char *p = s;&lt;br /&gt;
	while (*p!=0)&lt;br /&gt;
		++p;&lt;br /&gt;
	return p-s;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первая реализация более трудоемка, так как s[len] &amp;amp;lt;=&amp;amp;gt; *(s+len) то есть смещению по массиву и разименованию (2 операции), &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 foo (int *first, int *last);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Где first является указателем на первый элемент массивва (a[0]), а last указателем на область памяти сразу за массивом (&amp;quot;a[n]&amp;quot;). &lt;br /&gt;
Такой выбор указателя last обеспечивает работу с массивами нулевой длины.&lt;br /&gt;
Перепишем функцию max_element:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int* max_element (int *m, int *last)&lt;br /&gt;
{&lt;br /&gt;
	int *max = m;&lt;br /&gt;
	for (; m != last; ++m)&lt;br /&gt;
		if (*m &amp;gt;= *max)&lt;br /&gt;
			max = m;&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, a+5);&lt;br /&gt;
Следует отметить, что теперь функция max_element возвращает не значение&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 findch (char *s, char p)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
			return i;&lt;br /&gt;
	return -1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вообще данная функция должна информировать о двух вещах: во-первых, найден ли искомый символ, а во-вторых, если да, то его позицию. &lt;br /&gt;
Будет правильно возвращать 2 значения соответственно, а не совмещать все в одном. Перепишем функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool findch (char *s, char p, int *n=0)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
		{&lt;br /&gt;
			*n = i;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
	return false;&lt;br /&gt;
}&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 idx = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;idx)) {...}&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;
bool findch (char *s, char p, char **pos=0)&lt;br /&gt;
{&lt;br /&gt;
	while (*s!=0)&lt;br /&gt;
	{&lt;br /&gt;
		if (*s==p)&lt;br /&gt;
		{&lt;br /&gt;
			if (pos)&lt;br /&gt;
				*pos=s;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
		++s;&lt;br /&gt;
	}&lt;br /&gt;
	return false;&lt;br /&gt;
} &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;
char *pos = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;pos) {...}&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;
int a = 5;&lt;br /&gt;
int &amp;amp;amp;b = a; ''//b - ссылка на а''&lt;br /&gt;
&lt;br /&gt;
b = 10; ''//в а тоже стало 10''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Функция swap с использованием ссылок будет выглядеть так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int &amp;amp;amp;a, int &amp;amp;amp;b)&lt;br /&gt;
{&lt;br /&gt;
	int t=b;&lt;br /&gt;
	b=a;&lt;br /&gt;
	a=t;&lt;br /&gt;
}&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 c = 30;&lt;br /&gt;
swap (a, c);&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;
 * &amp;amp;amp;q	взятие адреса переменной q&lt;br /&gt;
 * *pa	  	разименование&lt;br /&gt;
 * int &amp;amp;amp;a	передача переменной а по ссылке&lt;br /&gt;
 * int *pa   	передача переменной по адресу.&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=162</id>
		<title>Указатели и ссылки</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=162"/>
				<updated>2011-03-30T07:58:36Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Встроенные массивы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;
Пример создания указателя на int и на double:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int a=5;&lt;br /&gt;
int *pa = &amp;amp;amp;a;&lt;br /&gt;
double d = 1.5;&lt;br /&gt;
double *pd = &amp;amp;amp;d;&lt;br /&gt;
&lt;br /&gt;
pa = pd //нельзя! т.к. указатели на данные разного типа&lt;br /&gt;
&lt;br /&gt;
pa = (int*)pd; //компилируется&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя операция лишена смысла, т.к. элемент типа double занимает 8 байт, а элемент типа int - 4 байта (в х32). &lt;br /&gt;
Поэтому указатель pa будет указывать на первые 4 байта данных, расположенных по&lt;br /&gt;
адресу, хранящемуся в pd.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример функции, которая должна менять местами два значения:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int a, int b)&lt;br /&gt;
{&lt;br /&gt;
	int t = a;&lt;br /&gt;
	a = b;&lt;br /&gt;
	b = t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (k, m);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Несмотря на то, что все написано правильно, после возврата из функции swap значения k и m не изменились. Это обусловлено &lt;br /&gt;
тем, что при передаче в функцию происходит копирование параметров. Таким образом, изменились скопированные значения, &lt;br /&gt;
а исходные остались прежними. Чтобы иметь возможность менять параметры их следует передавать по указателю:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int *a, int *b)&lt;br /&gt;
{&lt;br /&gt;
	int t = *a;&lt;br /&gt;
	*a = *b;&lt;br /&gt;
	*b = *t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (&amp;amp;amp;k, &amp;amp;amp;m);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Теперь значения k и m изменились, так как при передаче в функцию произошло копирование адресов переменных, а адреса мы менять не хотели.&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 a[5] = {1, 2, 3}; //в памяти лежат 1,2,3,0,0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 _ _ _  ___________________ _ _&lt;br /&gt;
 _ _ _ |_1_|_2_|_3_|_0_|_0_|_ _&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 *p = 0; //&amp;quot;нулевой&amp;quot; указатель, nil. Означает, что он не указывает ни на какую ячейку памяти.&lt;br /&gt;
p = a; // &amp;amp;amp;a[0]&lt;br /&gt;
a = 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;
int max_element (int m[10]) {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Массив передается по ссылке (не копируется).''&lt;br /&gt;
Вызов: max_element(a);&lt;br /&gt;
Функция max_element будет работать только с массивами из 10 элементов (с другими&lt;br /&gt;
- не скомпилируется). Правильнее делать так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int max_element (int *m, int size) &lt;br /&gt;
{&lt;br /&gt;
	int max = *m; &lt;br /&gt;
	for (int i=1; i &amp;amp;amp;lt size; ++i)&lt;br /&gt;
		if (m[i] &amp;amp;amp;lt max)&lt;br /&gt;
			max = m[i];&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, 5); &lt;br /&gt;
&lt;br /&gt;
Проблемы такой реализации:&lt;br /&gt;
* функция не работает с массивами нулевой длины;&lt;br /&gt;
* не отследить случаи выхода за границы массива.&lt;br /&gt;
&lt;br /&gt;
===Арифметика указателей===&lt;br /&gt;
Пусть q, p - указатели, а i - число. Возможные операции:&lt;br /&gt;
* p+i, p-i	сдвиг по массиву на i элементов вправо/влево&lt;br /&gt;
* p[i] &amp;amp;lt;=&amp;amp;gt; *(p+i)&lt;br /&gt;
* q-p		количество элементов массива между p и q. Разность указателей имеет тип size_t.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим две реализации функции подсчета длины символов в строке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int strlen1 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	int len=0;&lt;br /&gt;
	while (s[len]!=0)&lt;br /&gt;
		++len;&lt;br /&gt;
	return len;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int strlen2 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	char *p = s;&lt;br /&gt;
	while (*p!=0)&lt;br /&gt;
		++p;&lt;br /&gt;
	return p-s;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первая реализация более трудоемка, так как s[len] &amp;amp;lt;=&amp;amp;gt; *(s+len) то есть смещению по массиву и разименованию (2 операции), &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 foo (int *first, int *last);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Где first является указателем на первый элемент массивва (a[0]), а last указателем на область памяти сразу за массивом (&amp;quot;a[n]&amp;quot;). &lt;br /&gt;
Такой выбор указателя last обеспечивает работу с массивами нулевой длины.&lt;br /&gt;
Перепишем функцию max_element:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int* max_element (int *m, int *last)&lt;br /&gt;
{&lt;br /&gt;
	int *max = m;&lt;br /&gt;
	for (; m != last; ++m)&lt;br /&gt;
		if (*m &amp;gt;= *max)&lt;br /&gt;
			max = m;&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, a+5);&lt;br /&gt;
Следует отметить, что теперь функция max_element возвращает не значение&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 findch (char *s, char p)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
			return i;&lt;br /&gt;
	return -1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вообще данная функция должна информировать о двух вещах: во-первых, найден ли искомый символ, а во-вторых, если да, то его позицию. &lt;br /&gt;
Будет правильно возвращать 2 значения соответственно, а не совмещать все в одном. Перепишем функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool findch (char *s, char p, int *n=0)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
		{&lt;br /&gt;
			*n = i;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
	return false;&lt;br /&gt;
}&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 idx = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;idx)) {...}&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;
bool findch (char *s, char p, char **pos=0)&lt;br /&gt;
{&lt;br /&gt;
	while (*s!=0)&lt;br /&gt;
	{&lt;br /&gt;
		if (*s==p)&lt;br /&gt;
		{&lt;br /&gt;
			if (pos)&lt;br /&gt;
				*pos=s;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
		++s;&lt;br /&gt;
	}&lt;br /&gt;
	return false;&lt;br /&gt;
} &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;
char *pos = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;pos) {...}&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;
int a = 5;&lt;br /&gt;
int &amp;amp;amp;b = a; ''//b - ссылка на а''&lt;br /&gt;
&lt;br /&gt;
b = 10; ''//в а тоже стало 10''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Функция swap с использованием ссылок будет выглядеть так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int &amp;amp;amp;a, int &amp;amp;amp;b)&lt;br /&gt;
{&lt;br /&gt;
	int t=b;&lt;br /&gt;
	b=a;&lt;br /&gt;
	a=t;&lt;br /&gt;
}&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 c = 30;&lt;br /&gt;
swap (a, c);&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;
 * &amp;amp;amp;q	взятие адреса переменной q&lt;br /&gt;
 * *pa	  	разименование&lt;br /&gt;
 * int &amp;amp;amp;a	передача переменной а по ссылке&lt;br /&gt;
 * int *pa   	передача переменной по адресу.&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=161</id>
		<title>Указатели и ссылки</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=161"/>
				<updated>2011-03-30T07:56:57Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Указатели */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;
Пример создания указателя на int и на double:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int a=5;&lt;br /&gt;
int *pa = &amp;amp;amp;a;&lt;br /&gt;
double d = 1.5;&lt;br /&gt;
double *pd = &amp;amp;amp;d;&lt;br /&gt;
&lt;br /&gt;
pa = pd //нельзя! т.к. указатели на данные разного типа&lt;br /&gt;
&lt;br /&gt;
pa = (int*)pd; //компилируется&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя операция лишена смысла, т.к. элемент типа double занимает 8 байт, а элемент типа int - 4 байта (в х32). &lt;br /&gt;
Поэтому указатель pa будет указывать на первые 4 байта данных, расположенных по&lt;br /&gt;
адресу, хранящемуся в pd.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример функции, которая должна менять местами два значения:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int a, int b)&lt;br /&gt;
{&lt;br /&gt;
	int t = a;&lt;br /&gt;
	a = b;&lt;br /&gt;
	b = t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (k, m);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Несмотря на то, что все написано правильно, после возврата из функции swap значения k и m не изменились. Это обусловлено &lt;br /&gt;
тем, что при передаче в функцию происходит копирование параметров. Таким образом, изменились скопированные значения, &lt;br /&gt;
а исходные остались прежними. Чтобы иметь возможность менять параметры их следует передавать по указателю:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int *a, int *b)&lt;br /&gt;
{&lt;br /&gt;
	int t = *a;&lt;br /&gt;
	*a = *b;&lt;br /&gt;
	*b = *t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (&amp;amp;amp;k, &amp;amp;amp;m);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Теперь значения k и m изменились, так как при передаче в функцию произошло копирование адресов переменных, а адреса мы менять не хотели.&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 a[5] = {1, 2, 3}; ''//в памяти лежат 1,2,3,0,0''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 _ _ _  ___________________ _ _&lt;br /&gt;
 _ _ _ |_1_|_2_|_3_|_0_|_0_|_ _&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 *p = 0; ''//&amp;quot;нулевой&amp;quot; указатель, nil. Означает, что он не указывает ни на какую ячейку памяти.''&lt;br /&gt;
p = a; ''// &amp;amp;amp;a[0]''&lt;br /&gt;
&lt;br /&gt;
a = 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;
int max_element (int m[10]) {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Массив передается по ссылке (не копируется).''&lt;br /&gt;
Вызов: max_element(a);&lt;br /&gt;
Функция max_element будет работать только с массивами из 10 элементов (с другими&lt;br /&gt;
- не скомпилируется). Правильнее делать так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int max_element (int *m, int size) &lt;br /&gt;
{&lt;br /&gt;
	int max = *m; &lt;br /&gt;
	for (int i=1; i &amp;amp;amp;lt size; ++i)&lt;br /&gt;
		if (m[i] &amp;amp;amp;lt max)&lt;br /&gt;
			max = m[i];&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, 5); &lt;br /&gt;
&lt;br /&gt;
Проблемы такой реализации:&lt;br /&gt;
 * функция не работает с массивами нулевой длины;&lt;br /&gt;
 * не отследить случаи выхода за границы массива.&lt;br /&gt;
&lt;br /&gt;
===Арифметика указателей===&lt;br /&gt;
Пусть q, p - указатели, а i - число. Возможные операции:&lt;br /&gt;
 * p+i, p-i	сдвиг по массиву на i элементов вправо/влево&lt;br /&gt;
 * p[i] &amp;amp;lt;=&amp;amp;gt; *(p+i)&lt;br /&gt;
 * q-p		количество элементов массива между p и q. Разность указателей имеет тип size_t.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим две реализации функции подсчета длины символов в строке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int strlen1 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	int len=0;&lt;br /&gt;
	while (s[len]!=0)&lt;br /&gt;
		++len;&lt;br /&gt;
	return len;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int strlen2 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	char *p = s;&lt;br /&gt;
	while (*p!=0)&lt;br /&gt;
		++p;&lt;br /&gt;
	return p-s;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первая реализация более трудоемка, так как s[len] &amp;amp;lt;=&amp;amp;gt; *(s+len) то есть смещению по массиву и разименованию (2 операции), &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 foo (int *first, int *last);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Где first является указателем на первый элемент массивва (a[0]), а last указателем на область памяти сразу за массивом (&amp;quot;a[n]&amp;quot;). &lt;br /&gt;
Такой выбор указателя last обеспечивает работу с массивами нулевой длины.&lt;br /&gt;
Перепишем функцию max_element:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int* max_element (int *m, int *last)&lt;br /&gt;
{&lt;br /&gt;
	int *max = m;&lt;br /&gt;
	for (; m != last; ++m)&lt;br /&gt;
		if (*m &amp;amp;gt; *max)&lt;br /&gt;
			max = m;&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, a+5);&lt;br /&gt;
Следует отметить, что теперь функция max_element возвращает не значение&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 findch (char *s, char p)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
			return i;&lt;br /&gt;
	return -1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вообще данная функция должна информировать о двух вещах: во-первых, найден ли искомый символ, а во-вторых, если да, то его позицию. &lt;br /&gt;
Будет правильно возвращать 2 значения соответственно, а не совмещать все в одном. Перепишем функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool findch (char *s, char p, int *n=0)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
		{&lt;br /&gt;
			*n = i;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
	return false;&lt;br /&gt;
}&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 idx = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;idx)) {...}&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;
bool findch (char *s, char p, char **pos=0)&lt;br /&gt;
{&lt;br /&gt;
	while (*s!=0)&lt;br /&gt;
	{&lt;br /&gt;
		if (*s==p)&lt;br /&gt;
		{&lt;br /&gt;
			if (pos)&lt;br /&gt;
				*pos=s;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
		++s;&lt;br /&gt;
	}&lt;br /&gt;
	return false;&lt;br /&gt;
} &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;
char *pos = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;pos) {...}&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;
int a = 5;&lt;br /&gt;
int &amp;amp;amp;b = a; ''//b - ссылка на а''&lt;br /&gt;
&lt;br /&gt;
b = 10; ''//в а тоже стало 10''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Функция swap с использованием ссылок будет выглядеть так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int &amp;amp;amp;a, int &amp;amp;amp;b)&lt;br /&gt;
{&lt;br /&gt;
	int t=b;&lt;br /&gt;
	b=a;&lt;br /&gt;
	a=t;&lt;br /&gt;
}&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 c = 30;&lt;br /&gt;
swap (a, c);&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;
 * &amp;amp;amp;q	взятие адреса переменной q&lt;br /&gt;
 * *pa	  	разименование&lt;br /&gt;
 * int &amp;amp;amp;a	передача переменной а по ссылке&lt;br /&gt;
 * int *pa   	передача переменной по адресу.&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=160</id>
		<title>Указатели и ссылки</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%A3%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%B8_%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8&amp;diff=160"/>
				<updated>2011-03-30T07:55:33Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: Новая страница: «==Указатели== Указатель - это переменная, содержащая адрес другой переменной. Указатели оче…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;
Пример создания указателя на int и на double:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int a=5;&lt;br /&gt;
int *pa = &amp;amp;amp;a;&lt;br /&gt;
double d = 1.5;&lt;br /&gt;
double *pd = &amp;amp;amp;d;&lt;br /&gt;
&lt;br /&gt;
pa = pd ''//нельзя! т.к. указатели на данные разного типа''&lt;br /&gt;
&lt;br /&gt;
pa = (int*)pd; ''//компилируется''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Последняя операция лишена смысла, т.к. элемент типа double занимает 8 байт, а элемент типа int - 4 байта (в х32). &lt;br /&gt;
Поэтому указатель pa будет указывать на первые 4 байта данных, расположенных по&lt;br /&gt;
адресу, хранящемуся в pd.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример функции, которая должна менять местами два значения:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int a, int b)&lt;br /&gt;
{&lt;br /&gt;
	int t = a;&lt;br /&gt;
	a = b;&lt;br /&gt;
	b = t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (k, m);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Несмотря на то, что все написано правильно, после возврата из функции swap значения k и m не изменились. Это обусловлено &lt;br /&gt;
тем, что при передаче в функцию происходит копирование параметров. Таким образом, изменились скопированные значения, &lt;br /&gt;
а исходные остались прежними. Чтобы иметь возможность менять параметры их следует передавать по указателю:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int *a, int *b)&lt;br /&gt;
{&lt;br /&gt;
	int t = *a;&lt;br /&gt;
	*a = *b;&lt;br /&gt;
	*b = *t;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов swap:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int k=10, m=20;&lt;br /&gt;
swap (&amp;amp;amp;k, &amp;amp;amp;m);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Теперь значения k и m изменились, так как при передаче в функцию произошло копирование адресов переменных, а адреса мы менять не хотели. &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 a[5] = {1, 2, 3}; ''//в памяти лежат 1,2,3,0,0''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 _ _ _  ___________________ _ _&lt;br /&gt;
 _ _ _ |_1_|_2_|_3_|_0_|_0_|_ _&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 *p = 0; ''//&amp;quot;нулевой&amp;quot; указатель, nil. Означает, что он не указывает ни на какую ячейку памяти.''&lt;br /&gt;
p = a; ''// &amp;amp;amp;a[0]''&lt;br /&gt;
&lt;br /&gt;
a = 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;
int max_element (int m[10]) {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Массив передается по ссылке (не копируется).''&lt;br /&gt;
Вызов: max_element(a);&lt;br /&gt;
Функция max_element будет работать только с массивами из 10 элементов (с другими&lt;br /&gt;
- не скомпилируется). Правильнее делать так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int max_element (int *m, int size) &lt;br /&gt;
{&lt;br /&gt;
	int max = *m; &lt;br /&gt;
	for (int i=1; i &amp;amp;amp;lt size; ++i)&lt;br /&gt;
		if (m[i] &amp;amp;amp;lt max)&lt;br /&gt;
			max = m[i];&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, 5); &lt;br /&gt;
&lt;br /&gt;
Проблемы такой реализации:&lt;br /&gt;
 * функция не работает с массивами нулевой длины;&lt;br /&gt;
 * не отследить случаи выхода за границы массива.&lt;br /&gt;
&lt;br /&gt;
===Арифметика указателей===&lt;br /&gt;
Пусть q, p - указатели, а i - число. Возможные операции:&lt;br /&gt;
 * p+i, p-i	сдвиг по массиву на i элементов вправо/влево&lt;br /&gt;
 * p[i] &amp;amp;lt;=&amp;amp;gt; *(p+i)&lt;br /&gt;
 * q-p		количество элементов массива между p и q. Разность указателей имеет тип size_t.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим две реализации функции подсчета длины символов в строке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int strlen1 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	int len=0;&lt;br /&gt;
	while (s[len]!=0)&lt;br /&gt;
		++len;&lt;br /&gt;
	return len;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int strlen2 (char *s)&lt;br /&gt;
{&lt;br /&gt;
	char *p = s;&lt;br /&gt;
	while (*p!=0)&lt;br /&gt;
		++p;&lt;br /&gt;
	return p-s;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первая реализация более трудоемка, так как s[len] &amp;amp;lt;=&amp;amp;gt; *(s+len) то есть смещению по массиву и разименованию (2 операции), &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 foo (int *first, int *last);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Где first является указателем на первый элемент массивва (a[0]), а last указателем на область памяти сразу за массивом (&amp;quot;a[n]&amp;quot;). &lt;br /&gt;
Такой выбор указателя last обеспечивает работу с массивами нулевой длины.&lt;br /&gt;
Перепишем функцию max_element:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int* max_element (int *m, int *last)&lt;br /&gt;
{&lt;br /&gt;
	int *max = m;&lt;br /&gt;
	for (; m != last; ++m)&lt;br /&gt;
		if (*m &amp;amp;gt; *max)&lt;br /&gt;
			max = m;&lt;br /&gt;
	return max;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов: max_element(a, a+5);&lt;br /&gt;
Следует отметить, что теперь функция max_element возвращает не значение&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 findch (char *s, char p)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
			return i;&lt;br /&gt;
	return -1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вообще данная функция должна информировать о двух вещах: во-первых, найден ли искомый символ, а во-вторых, если да, то его позицию. &lt;br /&gt;
Будет правильно возвращать 2 значения соответственно, а не совмещать все в одном. Перепишем функцию:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool findch (char *s, char p, int *n=0)&lt;br /&gt;
{&lt;br /&gt;
	for (int i = 0; s[i] != 0; ++i)&lt;br /&gt;
		if (s[i] == p)&lt;br /&gt;
		{&lt;br /&gt;
			*n = i;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
	return false;&lt;br /&gt;
}&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 idx = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;idx)) {...}&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;
bool findch (char *s, char p, char **pos=0)&lt;br /&gt;
{&lt;br /&gt;
	while (*s!=0)&lt;br /&gt;
	{&lt;br /&gt;
		if (*s==p)&lt;br /&gt;
		{&lt;br /&gt;
			if (pos)&lt;br /&gt;
				*pos=s;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
		++s;&lt;br /&gt;
	}&lt;br /&gt;
	return false;&lt;br /&gt;
} &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;
char *pos = 0;&lt;br /&gt;
if (findch(s, ' ', &amp;amp;amp;pos) {...}&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;
int a = 5;&lt;br /&gt;
int &amp;amp;amp;b = a; ''//b - ссылка на а''&lt;br /&gt;
&lt;br /&gt;
b = 10; ''//в а тоже стало 10''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Функция swap с использованием ссылок будет выглядеть так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void swap (int &amp;amp;amp;a, int &amp;amp;amp;b)&lt;br /&gt;
{&lt;br /&gt;
	int t=b;&lt;br /&gt;
	b=a;&lt;br /&gt;
	a=t;&lt;br /&gt;
}&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 c = 30;&lt;br /&gt;
swap (a, c);&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;
 * &amp;amp;amp;q	взятие адреса переменной q&lt;br /&gt;
 * *pa	  	разименование&lt;br /&gt;
 * int &amp;amp;amp;a	передача переменной а по ссылке&lt;br /&gt;
 * int *pa   	передача переменной по адресу.&lt;/div&gt;</summary>
		<author><name>Katepol</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=159</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=159"/>
				<updated>2011-03-30T07:44:29Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Конспекты по C++&lt;br /&gt;
* [[ Как происходит компиляция|Как происходит компиляция. Алексей Давыдов. 08.09.2010]]&lt;br /&gt;
* [[ Указатели и ссылки|Указатели и ссылки. Екатерина Полищук. 10.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>Katepol</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=158</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=158"/>
				<updated>2011-03-30T07:43:52Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Конспекты по C++&lt;br /&gt;
* [[ Как происходит компиляция|Как происходит компиляция. Алексей Давыдов. 08.09.2010]]&lt;br /&gt;
* [[ Указатели|Указатели. Екатерина Полищук. 10.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>Katepol</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=156</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=156"/>
				<updated>2011-03-30T07:34:03Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Лабораторная работа №5 functor */&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;
&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>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7_%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9_%D1%81_%D1%86%D0%B5%D0%BB%D1%8C%D1%8E_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%BF%D0%BE%D1%85%D0%BE%D0%B6%D0%B8%D1%85_%D0%BB%D0%B8%D1%86&amp;diff=102</id>
		<title>Анализ изображений с целью поиска похожих лиц</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7_%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9_%D1%81_%D1%86%D0%B5%D0%BB%D1%8C%D1%8E_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%BF%D0%BE%D1%85%D0%BE%D0%B6%D0%B8%D1%85_%D0%BB%D0%B8%D1%86&amp;diff=102"/>
				<updated>2011-03-15T18:23:39Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Студент: Екатерина Полищук&lt;br /&gt;
&lt;br /&gt;
* Руководитель: Екатерина Тузова&lt;br /&gt;
&lt;br /&gt;
Описание: целью проекта является разработка приложения, реализующего автоматическую локализацию лица на фотографии и идентификацию персоны по лицу. В дальнейшем спецификация будет уточнена.&lt;br /&gt;
&lt;br /&gt;
Этапы:&lt;br /&gt;
* концепция приложения (20.03.2011)&lt;br /&gt;
* прототип приложения (альфа версия) (25.04.2011)&lt;br /&gt;
* бета версия приложения, итог (25.05.2011)&lt;br /&gt;
&lt;br /&gt;
Ожидаемый результат:&lt;br /&gt;
* приложение, опубликованное на http://code.google.com/&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7_%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9_%D1%81_%D1%86%D0%B5%D0%BB%D1%8C%D1%8E_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%BF%D0%BE%D1%85%D0%BE%D0%B6%D0%B8%D1%85_%D0%BB%D0%B8%D1%86&amp;diff=98</id>
		<title>Анализ изображений с целью поиска похожих лиц</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7_%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9_%D1%81_%D1%86%D0%B5%D0%BB%D1%8C%D1%8E_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%BF%D0%BE%D1%85%D0%BE%D0%B6%D0%B8%D1%85_%D0%BB%D0%B8%D1%86&amp;diff=98"/>
				<updated>2011-03-15T17:58:12Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Студент: Екатерина Полищук&lt;br /&gt;
&lt;br /&gt;
* Руководитель: Екатерина Тузова&lt;br /&gt;
&lt;br /&gt;
Описание: целью проекта является разработка приложения, реализующего автоматическую локализацию лица на фотографии и идентификация персоны по лицу. В дальнейшем спецификация будет уточнена.&lt;br /&gt;
&lt;br /&gt;
Этапы:&lt;br /&gt;
* концепция приложения (20.03.2011)&lt;br /&gt;
* прототип приложения (альфа версия) (25.04.2011)&lt;br /&gt;
* бета версия приложения, итог (25.05.2011)&lt;br /&gt;
&lt;br /&gt;
Ожидаемый результат:&lt;br /&gt;
* приложение, опубликованное на http://code.google.com/&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7_%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9_%D1%81_%D1%86%D0%B5%D0%BB%D1%8C%D1%8E_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%BF%D0%BE%D1%85%D0%BE%D0%B6%D0%B8%D1%85_%D0%BB%D0%B8%D1%86&amp;diff=75</id>
		<title>Анализ изображений с целью поиска похожих лиц</title>
		<link rel="alternate" type="text/html" href="http://mit.spbau.ru/sewiki/index.php?title=%D0%90%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7_%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9_%D1%81_%D1%86%D0%B5%D0%BB%D1%8C%D1%8E_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%BF%D0%BE%D1%85%D0%BE%D0%B6%D0%B8%D1%85_%D0%BB%D0%B8%D1%86&amp;diff=75"/>
				<updated>2011-03-12T21:00:30Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: Новая страница: «* Студент: Екатерина Полищук  * Руководитель: Екатерина Тузова  Описание: целью проекта явл…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Студент: Екатерина Полищук&lt;br /&gt;
&lt;br /&gt;
* Руководитель: Екатерина Тузова&lt;br /&gt;
&lt;br /&gt;
Описание: целью проекта является разработка приложения, реализующего автоматическую локализация лица на фотографии и идентификация персоны по лицу. В дальнейшем спецификация будет уточнена.&lt;br /&gt;
&lt;br /&gt;
Этапы:&lt;br /&gt;
* концепция приложения (20.03.2011)&lt;br /&gt;
* прототип приложения (альфа версия) (25.04.2011)&lt;br /&gt;
* бета версия приложения, итог (25.05.2011)&lt;br /&gt;
&lt;br /&gt;
Ожидаемый результат:&lt;br /&gt;
* приложение, опубликованное на http://code.google.com/&lt;/div&gt;</summary>
		<author><name>Katepol</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=74</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=74"/>
				<updated>2011-03-12T20:48:46Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Весна 2011 */&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;
== Пул свободных тем ==&lt;br /&gt;
&lt;br /&gt;
* [[GeoToDo list]]&lt;/div&gt;</summary>
		<author><name>Katepol</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%D1%86%D0%B0:Katepol&amp;diff=73</id>
		<title>Участница:Katepol</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%D1%86%D0%B0:Katepol&amp;diff=73"/>
				<updated>2011-03-11T07:33:28Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Екатерина Полищук */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Екатерина Полищук ==&lt;br /&gt;
&lt;br /&gt;
mailto: katepol14@gmail.com&lt;br /&gt;
&lt;br /&gt;
[[Файл:Kate1.jpg]]&lt;/div&gt;</summary>
		<author><name>Katepol</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%D1%86%D0%B0:Katepol&amp;diff=72</id>
		<title>Участница:Katepol</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%D1%86%D0%B0:Katepol&amp;diff=72"/>
				<updated>2011-03-11T07:32:48Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Екатерина Полищук */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Екатерина Полищук ==&lt;br /&gt;
&lt;br /&gt;
[[katepol14@gmail.com]]&lt;br /&gt;
&lt;br /&gt;
[[Файл:Kate1.jpg]]&lt;/div&gt;</summary>
		<author><name>Katepol</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%D1%86%D0%B0:Katepol&amp;diff=71</id>
		<title>Участница:Katepol</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%D1%86%D0%B0:Katepol&amp;diff=71"/>
				<updated>2011-03-11T07:32:07Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Екатерина Полищук */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Екатерина Полищук ==&lt;br /&gt;
&lt;br /&gt;
katepol14@gmail.com&lt;br /&gt;
&lt;br /&gt;
[[Файл:Kate1.jpg]]&lt;/div&gt;</summary>
		<author><name>Katepol</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%D1%86%D0%B0:Katepol&amp;diff=70</id>
		<title>Участница:Katepol</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%D1%86%D0%B0:Katepol&amp;diff=70"/>
				<updated>2011-03-11T07:31:24Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: /* Екатерина Полищук */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Екатерина Полищук ==&lt;br /&gt;
&lt;br /&gt;
katepol14@gmail.com&lt;br /&gt;
[[Файл:Kate1.jpg]]&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Kate1.jpg&amp;diff=69</id>
		<title>Файл:Kate1.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:Kate1.jpg&amp;diff=69"/>
				<updated>2011-03-11T07:30:18Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: загружена новая версия «Файл:Kate1.jpg»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	<entry>
		<id>http://mit.spbau.ru/sewiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Kate1.jpg&amp;diff=68</id>
		<title>Файл:Kate1.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:Kate1.jpg&amp;diff=68"/>
				<updated>2011-03-11T07:28:18Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Katepol</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%D1%86%D0%B0:Katepol&amp;diff=67</id>
		<title>Участница:Katepol</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%D1%86%D0%B0:Katepol&amp;diff=67"/>
				<updated>2011-03-11T07:27:32Z</updated>
		
		<summary type="html">&lt;p&gt;Katepol: Новая страница: «== Екатерина Полищук ==  katepol14@gmail.com Файл:/home/kate/Pictures/kate1.jpg»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Екатерина Полищук ==&lt;br /&gt;
&lt;br /&gt;
katepol14@gmail.com&lt;br /&gt;
[[Файл:/home/kate/Pictures/kate1.jpg]]&lt;/div&gt;</summary>
		<author><name>Katepol</name></author>	</entry>

	</feed>