C++ (Хилл, Страуструп) - страница 82

double f() (* // ... return 1; // неявно преобразуется к double(1) *)

Каждый раз, когда вызывается функция, создается новая копия ее параметров и автоматических переменных. После возрата из функции память используется заново, поэтому возврщать указатель на локальную переменную неразумно. Содержание указываемого места изменится непредсказуемо:

int* f() (* int local = 1; // ... return amp;local; // так не делайте *)

Эта ошибка менее обычна, чем эквивалентная ошибка при использовании ссылок:

int amp; f() (* int local = 1; // ... return local; // так не делайте *)

К счастью, о таких возвращаемых значениях предупреждает компилятор. Вот другой пример:

int amp; f() (* return 1;*) // так не делайте

4.6.5 Векторные Параметры

Если в качестве параметра функции используется вектор, то передается указатель на его первый элемент. Например:

int strlen(const char*);

void f() (* char v[] = «a vector» strlen(v); strlen(«Nicholas»); *);

Иначе говоря, при передаче как параметр параметр типа T[] преобразуется к T*. Следовательно, присваивание элементу векторного параметра изменяет значение элемента вектора, кторый является параметром. Другими словами, вектор отличается от всех остальных типов тем, что вектор не передается (и не может передаваться) по значению.

Размер вектора недоступен вызываемой функции. Это может быть неудобно, но эту сложность можно обойти несколькими спсобами. Строки оканчиваются нулем, поэтому их размер можно легко вычислить. Для других векторов можно передавать второй

параметр, который задает размер, или определить тип, содержщий указатель и индикатор длины, и передавать его вместо просто вектора (см. также #1.11). Например:

void compute1(int* vec_ptr, int vec_size); // один способ

struct vec (* // другой способ int* ptr; int size; *);

void compute2(vec v);

С многомерными массивами все хитрее, но часто можно вместо них использовать векторы указателей, которые не требют специального рассмотрения. Например:

char* day[] = (* «mon», «tue», «wed», «thu», «fri», «sat», «sun» *);

С другой стороны, рассмотрим определение функции, котрая работает с двумерными матрицами. Если размерность извесна на стадии компиляции, то никаких проблем нет:

void print_m34(int m[3][4]) (* for (int i = 0; i«3; i++) (* for (int j = 0; j„4; j++) cout «« " " «« m[i][j]; cout «« «\n“; *) *)

Матрица, конечно, все равно передается как указатель, а размерности используются просто для удобства записи.

Первая размерность массива не имеет отношения к задаче поиска положения элемента (#2.3.6). Поэтому ее можно передвать как параметр: