Если массив является глобальным, то его элементы могут быть инициализированы соответствующим значением, принятым для данного типа по умолчанию. Например, значение a[7]
равно 0
. Если массив является локальным (переменная объявлена в функции) или создан с помощью оператора new
, то элементы встроенных типов останутся неинициализированными, а элементы, имеющие пользовательский тип, будут инициализированы его конструкторами.
Имя массива неявно преобразуется в указатель на его первый элемент. Рассмотрим пример.
int* p = a; // указатель p ссылается на элемент a[0]
Массив или указатель на элемент массива может индексироваться с помощью оператора []
. Рассмотрим пример.
a[7] = 9;
int xx = p[6];
Элементы массива нумеруются начиная с нуля (разделы 18.5).
Диапазон индексов массива не проверяется. Кроме того, поскольку они часто передаются с помощью указателей, информация, необходимая для проверки диапазона, передается пользователям ненадежным способом. Рекомендуем использовать класс vector
. Размер массива — это сумма размеров его элементов. Рассмотрим пример.
int a[max]; // sizeof(a) == sizeof(int)*max
Можно определить и использовать массив массивов (двумерный массив), массив массивов массивов (многомерный массив) и т.д. Рассмотрим пример.
double da[100][200][300]; // 300 элементов типа, состоящего из
da[7][9][11] = 0;
Нетривиальное использование многомерных массивов — тонкое и уязвимое для ошибок дело (см. раздел 24.4). Если у вас есть выбор, следует предпочесть класс Matrix
(как в главе 24).
A.8.3. Ссылки
int a = 7;
int& r = a;
r = 8; // переменная a становится равной 8
Ссылки часто используются в качестве параметров функций, чтобы предотвратить копирование.
void f(const string& s);
// ...
f("эту строку слишком дорого копировать, \\
поэтому используется ссылка");
См. разделы 8.5.4–8.5.6.
A.9. Функции
char f(string, int);
Итак, f
— это функция, принимающая объекты типа string
и int
и возвращающая объект типа char
. Если функция должна быть просто объявлена, но не определена, то ее объявление завершается точкой с запятой. Если функция должна быть определена, то за объявлением аргументов следует тело функции.
char f(string s, int i) { return s[i]; }
Телом функции должен быть блок (см. раздел 8.2) или блок try
(см. раздел 5.6.3).
Функция, в объявлении которой указано, что она возвращает какое-то значение, должна его возвращать (используя оператор return
).
char f(string s, int i) { char c = s[i]; } // ошибка: ничего
// не возвращается
Функция main()
представляет собой странное исключение из этого правила (см. раздел A.1.2). За исключением функции main()
, если не хотите возвращать значение, то поставьте перед именем функции ключевое слово void
. Другими словами, используйте слово void
как тип возвращаемого значения.
void increment(int& x) { ++x; } // OK: возвращать значение
// не требуется
Функция вызывается с помощью оператора вызова ()
с соответствующим списком аргументов.
char x1 = f(1,2); // ошибка: первый аргумент функции f() должен
// быть строкой
string s = "Battle of Hastings";
char x2 = f(s); // ошибка: функция f() требует двух аргументов
char x3 = f(s,2); // OK
Более подробную информацию о функциях см. в главе 8.
A.9.1. Разрешение перегрузки
void print(int);
void print(double);
void print(const std::string&);
print(123); // вызывается print(int)
print(1.23); // вызывается print(double)
print("123"); // вызывается print(const string&)