Си++: различия между версиями
Содержимое удалено Содержимое добавлено
Andreyvit (обсуждение | вклад) Нет описания правки |
Andreyvit (обсуждение | вклад) Нет описания правки |
||
Строка 7:
== Основные отличия Си++ от Си ==
=== Использование ссылок; передача аргументов по ссылке ===
==== Передача параметров в Си ====
Строка 73:
После этого <tt>z</tt> и <tt>x</tt> обозначают одно и то же — некую область в памяти, в которой хранится целое число. Заметим, что эти две строки принципиально отличаются.
Во-первых, мы можем написать «<tt>int z = 7;</tt>», а можем:
int z = 7;▼
int z;
z = 7;
Это будет практически одно и то же.
Ссылки ведут себя совсем иначе. Запись «<tt>int &x = z;</tt>» означает, что «<tt>x</tt> отныне является ссылкой на область памяти, которая раньше называлась <tt>z</tt>». В то же время запись «<tt>x = z;</tt>» означала бы, что области памяти, на которую ссылается <tt>x</tt>, нужно присвоить значение переменной <tt>z</tt>. В нашем случае (когда <tt>x</tt> ссылается на <tt>z</tt>) это эквивалентно записи «<tt>z = z;</tt>».▼
int &x = z;▼
▲означала бы, что области памяти, на которую ссылается <tt>x</tt>, нужно присвоить значение переменной <tt>z</tt>. В нашем случае (когда <tt>x</tt> ссылается на <tt>z</tt>) это эквивалентно записи
Заметим, что когда мы пишем «<tt>int z;</tt>», то выделяется память для хранения величины типа <tt>int</tt>. А когда мы пишем
«<tt>int &x = z;</tt>», мы пользуемся «чужой» памятью, то есть памятью, выделенной когда-то кем-то.▼
int &x = z;▼
▲мы пользуемся «чужой» памятью, то есть памятью, выделенной когда-то кем-то.
Когда время жизни переменной <tt>z</tt> заканчивается (в нашем примере — когда мы возвращаемся из <tt>main()</tt>), выделенная память освобождается. Если на неё остались какие-то указатели и ссылки — это ваши проблемы, и ваша программа непременно вскоре упадёт. У нас такого не происходит, потому что пока жива ссылка <tt>x</tt>, жива и переменная <tt>z</tt>.
Строка 120 ⟶ 110 :
теперь x == z == zz == 5 */
Изменить указатель, скрытый за ссылкой <tt>x</tt>, нельзя — просто нет в Си++ оператора, позволяющего это сделать.
Ещё одно важное отличие — ссылка не может ссылаться «ни на что». То есть, если указатель может иметь значение ''NULL'' (что, как известно, является просто красивым названием для числа 0), то ссылка — нет.
==== Зачем нужны ссылки? ====
Мы не смогли прийти к какому-либо глубокомысленному заключению. Ссылки просто местами удобнее. Придумать ситуацию, когда ссылку нельзя было бы заменить указателем, мне и моим знакомым не удалось.
=== Использование констант ===
==== Общие соображения =====
Константы — это совсем просто. Константа — это переменная, которую обязательно инициализировать и которая после этого не меняет своего значения.
Константы были ещё в Си, но их никто не использовал, ибо они были кривые. Числовые константы делали с помощью <tt>#define</tt>, и это неплохо работало. Константы всех остальных типов использовали редко.
В Си++ константы и всё, с ними связанное, получило религиозный статус с приходом классов. Но этого мы сейчас касаться не будем. Сейчас мы разберёмся, чем отличаются константы Си++ от констант Си.
…А главное отличие — их теперь можно использовать! Например, можно написать так:
const int N = 10;
Возможно, вы не поверите, но в Си этого сделать было нельзя. Хотя значение <tt>N</tt> известно во время компиляции, но в Си компилятор «закрывал на это глаза». (Безусловно, у них были свои причины на это, для интересующихся — причины зовут «extern», но всё равно получилось не очень хорошо.)
А раз константы можно использовать, отчего же этого не делать? Они многим лучше, чем <tt>#define</tt>:
* они имеют тип, а значит, позволяют «на халяву» найти парочку ошибок в вашей программе;
* они могут быть не просто числом или строкой, но и какой-нибудь сложной структурой;
* их имена можно использовать при отладке (хотя с современными средствами это почти не актуально);
* они не имеют ''побочных эффектов'' и других классических проблем с макросами (отсылаю вас к предостережениям о директиве <tt>#define</tt>, написанных в любой хорошей книге по Си или Си++).
Константы обязательно инициализировать, например:
const int foo = 10; /* можно */
/* const int bar; -- нельзя */
И это, дамы и господа, логично! Если мы её не инициализируем, то вообще никогда не сможем ничего ей присвоить, ведь она же константа. А на фиг тогда она была бы нам нужна?
===== Константы и ссылки/указатели =====
Константы очень интересно сочетаются с указателями и ссылками. По крайней мере, это интересно выглядит. Посмотрите сами:
; <tt>const int *foo</tt> : Указатель на <tt>const int</tt>. Значение указателя изменить можно (так, чтобы он указывал на что-нибудь другое), а вот значение переменной, ''на которую'' он указывает, менять нельзя.
; <tt>int *const foo = &x</tt> : Константный (неизменный) указатель на <tt>int</tt>. Значение указателя менять нельзя (прям как будто это ссылка, а не указатель). Значение того, на что он указывает, менять можно. Заметьте, что константный указатель обязательно инициализировать, как и любую другую константу.
; <tt>const int *const foo = &x</tt> : Смесь двух предыдущих пунктов. Ничего нельзя изменить: ни значение указателя, ни значение того, на что он указывает. Опять же, инициализация обязательна.
У ссылок разнообразия значительно меньше, ибо «указательная» часть ссылки и так всегда константна. Значит, бывает только:
— ссылка на <tt>int</tt>, который мы (с помощью этой ссылки) не сможем изменить.
И, наконец, пусть наши заявления про неизменность ссылок обретут некий формальный вид. Следующие строки очень похожи по смыслу:
int *const bar = &x;
Фактически, после этого <tt>foo</tt> и <tt>bar</tt> отличаются только синтаксически (везде нужно писать <tt>*bar</tt>, но просто <tt>foo</tt>), и если мы везде заменим <tt>foo</tt> на <tt>*bar</tt> или наоборот, ничего не изменится.
=== Логический тип и перечисления ===
=== Операторы управления динамической памятью, инициализация массивов ===
=== Структура программы, раздельная компиляция и особенности использования статической памяти ===
=== Функциональный полиморфизм ===
=== Пространства имён и исключения ===
=== Библиотека ввода-вывода (<tt>iostream</tt>) ===
== Средства объектного программирования ==
== Средства объектно-ориентированного программирования ==
== Generic programming ==
== Стандартная библиотека ==
|