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

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

int *f();

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

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

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

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

#include

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; // подстрока не найдена

}

При выполнении этой версии программы получен следующий результат.

Найденная подстрока: три четыре

В данном случае, когда подстрока "три" была найдена в строке "один два три четыре", функция find_substr() возвратила указатель на начало искомой подстроки "три", который в функции main() был присвоен переменной substr. Таким образом, при выводе значения substr на экране отобразился остаток строки, т.е. "три четыре".

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

Прототипы функций

Прототип объявляет функцию до ее первого использования.

До сих пор в приводимых здесь примерах программ прототипы функций использовались без каких-либо разъяснений. Теперь настало время поговорить о них подробно. В C++ все функции должны быть объявлены до их использования. Обычно это реализуется с помощью прототипа функции. Прототипы содержат три вида информации о функции:

■ тип возвращаемого ею значения;

■ тип ее параметров;

■ количество параметров.

Прототипы позволяют компилятору выполнить следующие три важные операции.

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

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

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

Общая форма прототипа функции аналогична ее определению за исключением того, что в прототипе не представлено тело функции.

type func_name(type parm_name1, type parm_name2,

...,

type parm_nameN);

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

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги