Как вернуть указатель из функции c
Перейти к содержимому

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

  • автор:

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

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

Можно объявить 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 определение функции будет выглядеть более запутанным:

Возврат данных из функции

Проверяем в Atollic True Studio , gcc для STM32F205 :

Возврат данных из функции

Сразу для понимания пример :

То есть тот тип данных , что возвращается из функции создается в основной программе просто как переменная.

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

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

uint8_t str[] (внутри функции) — размещение в стеке
uint8_t *str размещение во флеше (это где константные данные и код хранится)

static uint8_t str[](вне / в функции) , uint8_t str[] (вне функции) — в статической памяти SRAM , она же куча, (эта та , которая очищается после выключения)

Выводы

Возврат указателя из функции возможен , но главный вопрос : указатель на кого ? . То есть где находится указуемый ? : если в стеке то нельзя, если в куче и флэше , то можно.

Возврат указателя из функции через параметр передаваемый в функцию

Это возможно только если передавать двойной указатель ** !

Если надо вернуть несколько указателей из функции

Тогда можно тупо возвращать по return структуру с нужным количеством параметров.

Возврат указателей

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

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

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

char *match(char с, char *s)
<
register int count;
count = 0;
while(c!=s[count] && s[count]) count++;
return(&s[count]);
>

Функция match() пытается вернуть указатель на позицию в строке, где первый раз найден символ с. Если не найдено соответствие, возвращается указатель, содержащий NULL. Ниже показана небольшая программа, использующая match():

#include <stdio.h>
#include <conio.h>

char *match(char c*, char *s);

int main(void)
<
char s[80], *p, ch;
gets (s) ;
ch = getche();
p = match(ch, s);
if (p) /* совпадение */
printf(«%s «, p);
else
printf(«No match found.»);
return 0;
>

Данная программа осуществляет чтение строки, а затем символа. Если символ содержится в строке, то выводится строка, начиная с момента совпадения. Иначе выводится «No match found».

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

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

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

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

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

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

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

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *