Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Void power(int base, int exp)



{

  int i;

  if(exp< 0) return; /* Чтобы не допустить возведения числа в отрицательную степень, здесь выполняется возврат в вызывающую функцию и игнорируется остальная часть функции. */

  i = 1;

  for(; exp; exp--) i = base * i;

  cout < < " Результат равен: " < < i;

}

Функция может содержать несколько инструкций return. Функция будет завершена при выполнении хотя бы одного из них. Например, следующий фрагмент кода совершенно правомерен.

Void f()

{

  //...

  switch(с) {

    case 'a': return;

    case 'b': //...

    case 'c': return;

  }

  if(count< 100) return;

  //...

}

Однако следует иметь в виду, что слишком большое количество инструкций return может ухудшить ясность алгоритма и ввести в заблуждение тех, кто будет в нем разбираться. Несколько инструкций return стоит использовать только в том случае, если они способствуют ясности функции.

Возврат значений

Каждая функция, кроме типа void, возвращает какое-нибудь значение. Это значение явно задается с помощью инструкции return. Другими словами, любую не void-функцию можно использовать в качестве операнда в выражении. Следовательно, каждое из следующих выражений допустимо в C++.

х = power(у);

if(max(х, у)) > 100) cout < < " больше";

switch(abs (х)) {

Несмотря на то что все не void-функции возвращают значения, они необязательно должны быть использованы в программе. Самый распространенный вопрос относительно значений, возвращаемых функциями, звучит так: " Поскольку функция возвращает некоторое значение, то разве я не должен (должна) присвоить это значение какой-нибудь переменной? ". Ответ: нет, это необязательно. Если значение, возвращаемое функцией, не участвует в присваивании, оно попросту отбрасывается (теряется).

Рассмотрим следующую программу, в которой используется стандартная библиотечная функция abs().

#include < iostream>

#include < cstdlib>

using namespace std;

Int main()

{

  int i;

  i = abs(-10); // строка 1

  cout < < abs(-23); // строка 2

  abs(100); // строка 3

  return 0;

}

Функция abs() возвращает абсолютное значение своего целочисленного аргумента. Она использует заголовок < cstdlib> . В строке 1 значение, возвращаемое функцией abs(), присваивается переменной i. В строке 2 значение, возвращаемое функцией abs(), ничему не присваивается, но используется инструкцией cout. Наконец, в строке 3 значение, возвращаемое функцией abs(), теряется, поскольку не присваивается никакой другой переменной и не используется как часть выражения.

Если функция, тип которой отличен от типа void, завершается в результате обнаружения закрывающейся фигурной скобки, то значение, которое она возвращает, не определено (т.е. неизвестно). Из-за особенностей формального синтаксиса C++ не void-функция не обязана выполнять инструкцию return. Это может произойти в том случае, если конец функции будет достигнут до обнаружения инструкции return. Но, поскольку функция объявлена как возвращающая значение, значение будет таки возвращено, даже если это просто " мусор". В общем случае любая создаваемая вами не void-функция должна возвращать значение посредством явно выполняемой инструкции return.

Выше упоминалось, что void-функция может иметь несколько инструкций return. То же самое относится и к функциям, которые возвращают значения. Например, представленная в следующей программе функция find_substr() использует две инструкции return, которые позволяют упростить алгоритм ее работы. Эта функция выполняет поиск заданной подстроки в заданной строке. Она возвращает индекс первого обнаруженного вхождения заданной подстроки или значение -1, если заданная подстрока не была найдена. Например, если в строке " Я люблю C++ " необходимо отыскать подстроку " люблю" , то функция find_substr() возвратит число 2 (которое представляет собой индекс символа " л" в строке " Я люблю C++ " ).

#include < iostream>

using namespace std;

int find_substr(char *sub, char *str);

Int main()

{

  int index;

  index = find_substr(" три", " один два три четыре" );

  cout < < " Индекс равен " < < index; // Индекс равен 9.

  return 0;

}

// Функция возвращает индекс искомой подстроки или -1, если она не была найдена.

int find_substr(char *sub, char *str)

{

  int t;

  char *p, *p2;

  for(t=0; str[t]; t++) {

    p = & str[t]; // установка указателей

    p2 = sub;

    while(*p2 & & *p2==*p) { // проверка совпадения

      p++; p2++;

    }

    /* Если достигнут конец р2-строки (т.е. подстроки), то подстрока была найдена. */

    if(! *p2) return t; // Возвращаем индекс подстроки.

  }

  return -1; // Подстрока не была обнаружена.

}

Результаты выполнения этой программы таковы.

Индекс равен 9

Поскольку искомая подстрока существует в заданной строке, выполняется первая инструкция return. В качестве упражнения измените программу так, чтобы ею выполнялся поиск подстроки, которая не является частью заданной строки. В этом случае функция find_substr() должна возвратить значение -1 (благодаря второй инструкции return).

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

Функции, которые не возвращают значений (void-функции)

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

#include < iostream>

using namespace std;

void print_vertical(char *str);

int main(int argc, char *argv[])

{

  if(argc==2) print_vertical(argv[1]);

  return 0;

}

void print_vertical(char *str)

{

  while(*str)

  cout < < *str++ < < '';

}

Поскольку print_vertical() объявлена как void-функция, ее нельзя использовать в выражении. Например, следующая инструкция неверна и поэтому не скомпилируется.

х = print_vertical(" Привет! " ); // ошибка

Важно! В первых версиях языка С не был предусмотрен тип void. Таким образом, в старых С-программах функции, не возвращающие значений, по умолчанию имели тип int. Если вам придется встретиться с такими функциями при переводе старых С-программ " на рельсы" C++, просто объявите их с использованием ключевого слова void, сделав их void-функциями.

Функции, которые возвращают указатели

Функции могут возвращать указатели. Указатели возвращаются подобно значениям любых других типов данных и не создают при этом особых проблем. Но, поскольку указатель представляет собой одно из самых сложных (или небезопасных) средств языка C++, имеет смысл посвятить ему отдельный раздел.

Чтобы вернуть указатель, функция должна объявить его тип в качестве типа возвращаемого значения. Вот как, например, объявляется тип возвращаемого значения для функции f(), которая должна возвращать указатель на целое число.

int *f();

Если функция возвращает указатель, то значение, используемое в ее инструкции return, также должно быть указателем. (Как и для всех функций, return-значение должно быть совместимым с типом возвращаемого значения.)

В следующей программе демонстрируется использование указателя в качестве типа возвращаемого значения. Это — новая версия приведенной выше функции find_substr(), только теперь она возвращает не индекс найденной подстроки, а указатель на нее. Если заданная подстрока не найдена, возвращается нулевой указатель.

// Новая версия функции find_substr().

// которая возвращает указатель на подстроку.

#include < iostream>

using namespace std;

char *find_substr(char *sub, char *str);

Int main()

{

  char *substr;

  substr = find_substr(" три", " один два три четыре" );

  cout < < " Найденная подстрока: " < < substr;

  return 0;

}

// Функция возвращает указатель на искомую подстроку или нуль, если таковая не будет найдена.

char *find_substr(char *sub, char *str)

{

  int t;

  char *p, *p2, *start;

  for(t=0; str[t]; t++) {

    p = & str[t]; // установка указателей

    start = p;

    р2 = sub;

    while(*р2 & & *p2==*p) { // проверка совпадения

      р++; р2++;

    }

    /* Если достигнут конец р2-подстроки, то эта подстрока была найдена. */


    if(! *р2) return start; // Возвращаем указатель на начало найденной подстроки.

  }

  return 0; // подстрока не найдена

}


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-03-17; Просмотров: 1301; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.039 с.)
Главная | Случайная страница | Обратная связь