Ссылка объявляется аналогично указателю с использованием
В конце концов, заменяя в списке параметров
В предыдущем примере использовались константные ссылки, не позволяющие модифицировать в функции объекты, обращение к которым осуществляется с помощью ссылок. Когда желателен этот побочный эффект, можно передавать неконстантную ссылку или указатель. Например:
void transpose(Point2D &point)
{
double oldX = point.x;
point.setX(point.y);
point.setY(oldX);
}
В некоторых случаях имеется ссылка и требуется вызвать функцию, которая принимает указатель и наоборот. Для преобразования ссылки в указатель можно просто использовать унарный оператор
Point2D point;
Point2D &ref = point;
Point2D *ptr = &ref
Для преобразования указателя в ссылку используется унарный оператор
Point2D point;
Point2D *ptr = &point
Point2D &ref = *ptr;
Ссылки и указатели представляются в памяти одинаково и часто могут использоваться вместо друг друга, из-за чего возникает естественный вопрос о том, в каких случаях что из них следует предпочесть. С одной стороны, ссылки имеют более удобный синтаксис, с другой стороны — указатели в любой момент можно вновь устанавливать на указатель другого объекта, они могут содержать нулевое значение и более явный синтаксис их применения часто является неприятностью, неожиданно оказавшейся благом. По этим причинам предпочтение часто отдается указателям, а ссылки почти исключительно используются при объявлении параметров функций совместно с ключевым словом
Массивы
Массивы в С++ объявляются с указанием количества элементов массива в квадратных скобках после имени переменной массива. Допускаются двумерные массивы, т.е. массив массивов. Ниже приводится определение одномерного массива, содержащего 10 элементов типа
int fibonacci[10];
Доступ к элементам осуществляется с помощью следующей записи:
int fibonacci[10] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
В таких случаях можно не указывать размер массива, поскольку компилятор может его рассчитать по количеству элементов в списке инициализации:
int fibonacci[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
Статическая инициализация также работает для сложных типов, например для
Point2D triangle[] = {
Point2D(0.0, 0.0), Point2D(1.0, 0.0), Point2D(0.5, 0.866)
};
Если не предполагается в дальнейшем изменять массив, его можно сделать константным:
const int fibonacci[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
Для нахождения количества элементов в массиве можно использовать оператор
int n = sizeof(fibonacci) / sizeof(fibonacci[0]);
Оператор
enum { NFibonacci = 10 };
const int fibonacci[NFibonacci] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
Есть соблазн объявить константу как переменную типа
Проход в цикле по массиву обычно выполняется с использованием переменной целого типа. Например:
for (int i = 0; i < NFibonacci; ++i)
cout << fibonacci[i] << endl;
Массив можно также проходить с помощью указателя:
const int *ptr = &fibonacci[0];
while (ptr != &fibonacci[10]) {
cout << *ptr << endl;
++ptr;
}