Читать интересную книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 83 84 85 86 87 88 89 90 91 ... 337
не поступайте так. Компилятор выдаст ошибку.

• Блоки в функциях и других блоках: вложенные блоки.

void f(int x, int y)

{

  if (x>y) {

    // ...

  }

  else {

    // ...

  {

    // ...

  }

    // ...

  }

}

Вложенные блоки неизбежны, но они свидетельствуют о завышенной сложности программы и уязвимы для ошибок.

В языке C++ существует еще одно средство — namespace, которое используется исключительно для разграничения областей видимости (раздел 8.7).

 

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

// опасно уродливый код

struct X {

void f(int x) {

struct Y {

int f() { return 1; } int m; };

int m;

m=x; Y m2;

return f(m2.f()); }

int m; void g(int m) {

if (m) f(m+2); else {

g(m+2); }}

X() { } void m3() {

}

void main() {

X a; a.f(2);}

};

Неудобочитаемый код обычно скрывает ошибки. Если вы используете интегрированные среды разработки программ, то они автоматически выравнивают фигурные скобки (в соответствии со своими установками). Кроме того, существуют “программы изящного форматирования”, которые переформатируют исходный код в файле (часто предлагая пользователю выбор). Однако окончательная ответственность за удобочитаемость кода лежит на его авторе. 

8.5. Вызов функции и возврат значения

 

 Функции позволяют нам выражать действия и вычисления. Если мы хотим сделать что-то, заслуживающее названия, то пишем функцию. В языке С++ есть операторы (такие как + и *), с помощью которых можно вычислить новые значения по операндам, входящим в выражение, и инструкции (такие как for и if), позволяющие управлять порядком вычислений. Для того чтобы организовать код из этих примитивов, у нас есть функции.

Для выполнения своего предназначения функции принимают аргументы и, как правило, возвращают результат. В этом разделе мы рассмотрим механизмы передачи аргументов. 

8.5.1. Объявление аргументов и тип возвращаемого значения

Функции в языке С++ используются для названия и представления вычислений и действий. Объявление функции состоит из типа возвращаемого значения, за которым следует имя функции и список формальных аргументов. Рассмотрим пример.

double fct(int a, double d); // объявление функции fct (без тела)

double fct(int a, double d) { return a*d; } // объявление функции fct

Определение состоит из тела функции (инструкций, выполняемых при ее вызове), в то время как объявление, не являющееся определением, просто завершается точкой с запятой. Формальные аргументы часто называют параметрами (parameters). Если не хотите, чтобы функция имела аргументы, не указывайте параметры. Например:

int current_power(); // функция current_power не имеет аргументов

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

void increase_power(int level); // функция increase_power

                                // ничего не возвращает

Здесь ключевое слово void означает “ничего не возвращает”. Параметры можно как именовать, так и не именовать. Главное, чтобы объявления и определения были согласованы друг с другом. Рассмотрим пример.

// поиск строки s в векторе vs;

// vs[hint] может быть подходящим местом для начала поиска

// возвращает индекс найденного совпадения; –1 означает "не найдена"

int my_find(vector<string> vs, string s, int hint); // именованные

                                                    // аргументы

int my_find(vector<string>, string, int); // неименованные аргументы

 

 В объявлениях имена формальных аргументов не обязательны, просто они очень полезны для создания хороших комментариев. С точки зрения компилятора второе объявление функции my_find() так же правильно, как и первое: оно содержит всю информацию, необходимую для ее вызова.

Как правило, все аргументы в объявлении имеют имена. Рассмотрим пример.

int my_find(vector<string> vs, string s, int hint)

// поиск строки s в векторе vs, начиная с позиции hint

{

  if (hint<0 || vs.size()<=hint) hint = 0;

  for (int i = hint; i<vs.size(); ++i) // поиск, начиная

                                       // с позиции hint

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

  if (0<hint) {     // если строка s не была найдена на позиции до hint

    for (int i = 0; i<hint; ++i)

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

  }

  return –1;

}

Переменная hint немного усложняет код, но она введена на основании предположения, что пользователю может быть примерно известно, где в векторе находится строка. Однако представим себе, что мы использовали my_find(), а затем выяснили, что пользователи редко используют переменную hint, так что она лишь снижает производительность программы. В таком случае переменная hint больше не нужна, но за пределами нашего фрагмента есть множество вызовов функции my_find() с аргументом hint. Переписывать код мы не хотим (или не можем), поэтому изменять объявления функции my_find() не будем. Вместо этого мы просто не будем использовать последний аргумент. Поскольку мы его не используем, оставим его без имени.

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

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

1 ... 83 84 85 86 87 88 89 90 91 ... 337
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп.
Книги, аналогичгные Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Оставить комментарий