Литмир - Электронная Библиотека
A
A

int my_find(vector<string> vs, string s, int) // 3-й аргумент

                                              // не используется

{

 for (int i = 0; i<vs.size(); ++i)

   if (vs[i]==s) return i;

 return –1;

}

Полная грамматика объявлений функций изложена в книге Язык программирования С++ Страуструпа и в стандарте ISO C++.

8.5.2. Возврат значения

Функция возвращает вычисленное значение с помощью инструкции

return
.

T f() // функция f() возвращает объект класса T

{

  V v;

  // ...

  return v;

}

T x = f();

Здесь возвращаемое значение — это именно то значение, которые мы получили бы при инициализации переменной типа

T
значением типа
V
.

V v;

// ...

T t(v); // инициализируем переменную t значением v

Таким образом, возвращаемое значение — это форма инициализации. Функция, объявившая возвращение значения, должна его возвращать. Например, в следующем фрагменте возникает ошибка:

double my_abs(int x) // предупреждение: этот код содержит ошибки

{

  if (x < 0)

    return –x;

  else if (x > 0)

    return x;

} // ошибка: если х равно нулю, функция ничего не возвращает

На самом деле компилятор может не заметить, что вы “забыли” про вариант

x=0
. Лишь некоторые компиляторы умеют это делать. Тем не менее, если функция сложна, компилятор может не разобраться, возвращает ли она значение или нет, так что следует быть осторожным. Это значит, что программист сам должен убедиться, что функция содержит инструкцию
return
или вызов функции
error()
как возможный вариант выхода.

По историческим причинам функция

main()
представляет собой исключение из правила. Выход из функции
main()
в ее последней точке эквивалентен инструкции
return 0
, означающей успешное завершение программы.

В функции, не возвращающей никаких значений, инструкцию

return
можно использовать для выхода из нее, не указывая возвращаемую переменную. Рассмотрим пример.

void print_until_s(vector<string> v, string quit)

{

  for(int i=0; i<v.size(); ++i) {

    if (v[i]==quit) return;

    cout << v[i] << '\n';

  }

}

Как видим, достичь последней точки функции, перед именем которой стоит ключевое слово

void
, вполне возможно. Это эквивалентно инструкции
return;
.

8.5.3. Передача параметров по значению

 

Программирование. Принципы и практика использования C++ Исправленное издание - _002.png
 Простейший способ передать аргумент функции заключается в пересылке копии его значения. Аргумент функции
f()
является локальной переменной, которая инициализируется при каждом ее вызове. Рассмотрим пример.

// передача по значению (функция получает копию передаваемого

// значения)

int f(int x)

{

  x = x+1; // присваиваем локальной переменной x новое значение

  return x;

}

int main()

{

  int xx = 0;

  cout << f(xx) << endl; // вывод: 1

  cout << xx << endl;    // вывод: 0; функция f() не изменяет xx

  int yy = 7;

  cout << f(yy) << endl; // вывод: 8

  cout << yy << endl;    // вывод: 7; функция f() не изменяет yy

}

Поскольку в функцию передается копия, инструкция

x=x+1
в функции
f()
не изменяет значения переменных
xx
и
yy
, передаваемых ей при двух вызовах. Передачу аргумента по значению можно проиллюстрировать следующим образом.

Программирование. Принципы и практика использования C++ Исправленное издание - _066.png

Передача по значению представляет собой довольно простой механизм, а ее стоимость определяется стоимостью копирования значения. 

8.5.4. Передача параметров по константной ссылке

Передача по значению проста, понятна и эффективна, если передаются небольшие значения, например переменные типа

int
,
double
или
Token
(см. раздел 6.3.2). А что если передаваемое значение велико и представляет собой изображение (занимающее несколько миллионов бит), большую таблицу чисел (например, несколько тысяч целых чисел) или длинную строку (например, сотни символов)? Тогда копирование оказывается очень затратным механизмом. Не стоит слишком сильно беспокоиться о стоимости выполняемых операций, но делать ненужную работу также не следует, так как это свидетельствует о плохом воплощении идеи, которую мы хотим реализовать. Например, можно написать следующую функцию, выводящую на экран вектор чисел с плавающей точкой:

113
{"b":"847443","o":1}