Как вернуть указатель из функции c

от admin

Указатель в качестве возвращаемого значения функции

Функции могут не только принимать указатели в качестве аргументов, но и возвращать их.

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

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

// Пример 7.3. Функция возвращает указатель.

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

using namespace std;

int* fun(int*, int*);

int a = 2, b = 7, * p;

int* fun(int* x, int* y)<

if(*x > *y)return x; else return y;

// Пример 7.5. Функция возвращает указатель.

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

using namespace std;

int* fun(int, int);

int a = 2, b = 1, *p;

int* fun(int x, int y)<

if(x > y) t = &x; else t = &y;

Некоторые особенности использования указателей Нулевые указатели

Нулевой указатель – это указатель, который в данный момент не адресует никакого достоверного значения в памяти. Значение нулевого указателя равно нулю – единственный адрес, к которому нет доступа.

Указателю можно присвоить нулевой адрес следующим оператором:

Существует стандартная описанная во многих заголовочных файлах константа NULL, обозначающая нулевой адрес. Таким образом, предыдущему оператору равносилен следующий оператор:

int *p = NULL;

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

Как и другие глобальные переменные, глобальные указатели инициализируются значениями, равными нулю, во всех остальных случаях требуется явная инициализация, например, int *p = &c;

Часто при программировании используются проверки вида

if(p != NULL) оператор; // выполняется оператор, если

// p адресует достоверные данные

if(!p) оператор; // равнозначная запись

Указатели на тип void

В языке С++ можно встретить также указатели типа void, которые указывают на неопределённый тип данных:

Указателю на void можно присвоить адрес данного любого типа, но указатель на void нельзя разыменовать, пока он не приведён к какому-либо конкретному типу, так как неизвестно, на какой объём памяти он указывает:

void *p; double f = 12.34;

Не следует путать нулевой указатель и указатель на тип void. Нулевой указатель не адресует достоверных данных, а указатель на void адресует данные неопределённого типа и также может быть нулевым.

Указатель на void нельзя разыменовать, пока он не приведён к конкретному типу

Указатели на константу и константные указатели

При объявлении указателей, как и обычных переменных, может использоваться спецификатор const. Например, в следующих операторах

int x = 15, k = 10; const int * p = &x;

наличие спецификатора const означает, что указатель содержит адрес константы, следовательно, значение, находящееся по данному адресу, меняться не может, т.е. при выполнении оператора *p = 7;

компилятором будет выдано сообщение об ошибке. Но в этом случае возможно выполнение оператора p = &k;

Если же спецификатор const стоит между символом * и именем указателя, то сам указатель является константой:

int x = 15, k=10; int* const p = &x;

При этом можно выполнить оператор *p = 7;, но p = &k; – нельзя (компилятором будет выдано сообщение об ошибке).

Если же в объявлении будет два спецификатора const, как например, в следующих операторах

int x = 15, k = 10; const int* const p = &x;

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

// Пример 7.4. Использование сonst-указателя и указателя на сonst.

Способы возврата значения из функции

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

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

В остальных случаях в объявлении и определении функции перед названием функции задается возвращаемый тип данных. Значение этого типа должно быть указано в операторе return . В этом случае возвращается копия значения. Функция может вернуть значение любого типа, кроме массива. Работать с массивами необходимо через параметры функции, передавая указатель на него, или возвращая указатель на конкретный элемент. Вызов функции, возвращающей какое-либо значение, можно разместить внутри выражения с правой стороны от оператора = . Если функция возвращает ссылку, то допускается размещение функции и с левой стороны от оператора = . Возвращаемое значение можно присвоить переменной или просто проигнорировать. Пример функции, возвращающей копию значения:

Читать:
1с передать в запрос структуру как параметр

При использовании оператора return не должно быть неоднозначных ситуаций. Например, в этом случае возвращаемое значение зависит от условия:

Если переменная x имеет значение больше нуля, то все будет нормально, но если переменная равна нулю или имеет отрицательное значение, то возвращаемое значение не определено и функция вернет произвольное значение, так называемый «мусор». В этом случае при компиляции выводится предупреждающее сообщение: warning: control reaches end of non-void function . Чтобы избежать подобной ситуации, следует в конце тела функции вставить оператор return со значением по умолчанию:

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

Листинг 12.22. Возврат указателя

В языке C++ функции могут возвращать также ссылки. В этом случае допускается размещение функции как с правой, так и с левой стороны от оператора = . Чтобы функция возвращала ссылку необходимо в объявлении и определении после типа данных указать оператор & . В качестве примера напишем функцию, которая позволяет получить или изменить значение элемента массива по указанному индексу (листинг 12.23).

Листинг 12.23. Возврат ссылки


Учебник C++ (Qt Creator и MinGW) в формате PDF

Помощь сайту

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

Как вернуть указатель из функции c

В прошлой теме рассматривались такие функции, как calloc, malloc, realloc, которые возвращали в качестве результата указатель. То есть функция может не принимать указатели как параметры, но и возвращать указатель. Определение подобной функции выглядит следующим образом:

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

Функция addArrays() для хранения результатов сложения двух массивов выделяет динамическую память, на которую указывает указатель ptr. Затем эта динамическая память наполняется результатами сложения соответствующих элементов двух массивов. А возвращаемым значением служит указатель ptr.

В функции main мы можем получить возвращаемый указатель и перебрать все значения из динамической памяти:

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

Результатом работы программы будет следующий вывод:

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

Однако мы даже не сможем скомпилировать данный пример, так как массив ptr здесь задан как локальная переменная.

Возврат указателя на функцию

Каким образом можно вернуть указатель на функцию из функции?

Можно объявить auto возвращаемым типом, но так не интересно!

torokhkun's user avatar

Чтобы вернуть указатель на функцию, можно использовать следующие способы.

1) Явное указание типа.

2) Объявление синонима типа через typedef .

3) Объявление синонима типа через using ( c++11 ).

4) Полуавтоматическое определение возвращаемого типа ( c++11 ).

5) Автоматическое определение возвращаемого типа ( c++14 ).

Нашел ответ на англоязычном SO.

В вашем случае правильное определение для f1 будет:

В общем случае сигнатура должна быть такая:

Вообще, не рекомендую использовать такой синтаксис, т.к. сигнатура получается нечитаемой. Лучше создать аллиас на возвращаемый тип с помощью using или typedef :

Glorfindel's user avatar

Чтобы не запутаться в синтаксисе, вы можете просто объявить с помощью typedef имя типа. который собираетесь вернуть из функции.

И затем записываете

Без использование typedef определение функции будет выглядеть более запутанным:

Похожие статьи