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

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

  • автор:

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

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

Указатели на переменные — это не целые числа и не беззнаковые целые. Это адрес памяти некоторого типа данных. Причина такого разделения состоит в том, что когда выполняются арифметические действия с указателем, изменения происходят с учетом базового типа, то есть, если указатель на целое увеличивается, он будет содержать значение на 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():

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».

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

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

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

void (*f1())(char)

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

typedef void (*TFunc)(char); TFunc f1()

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

using TFunc = void (*)(char); TFunc f1()

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

auto f1() -> decltype(&f0)

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

auto f1()

Отслеживать
23.8k 3 3 золотых знака 46 46 серебряных знаков 61 61 бронзовый знак
ответ дан 1 дек 2015 в 7:16
user194374 user194374

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

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

void (*f1())(char)

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

возвращаемое_значение_возвращаемой_функции (*имя_функции(типы_параметров_функции))(типы_параметров_возвращаемой_функции); 

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

using Function = void (*)(char); Function f1()

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

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

// пример некорректного возвращения значения int* max(int a, int b) < if (a >b) return &a; else return &b; >

Параметры функции аналогичны переменным — при вызове функции в стеке для них выделяется память. И вданном случае возвращается адрес участка памяти соответствующего параметра ( return &a или return &b ). Но после возвращения адреса функция завершает свою работу, соответствующие участки памяти очищаются, параметры удаляются, поэтому возвращенный адрес будет недействительным. И хотя компилятор даже может скомпилировать данную функцию, ограничившись предупреждениями, но такая функция не будет работать корректно.

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

#include int* max(int*, int*); int main() < int n; int m; int* ptr = max(&n, &m); std::cout // пример корректного возвращения значения int* max(int *a, int *b) < if (*a >*b) // разыменовываем указатели return a; else return b; >

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

При этом нам необязательно присваивать результат переменной или константе, можно напрямую обратиться к результату функции:

int main() < int n; int m; std::cout 

Возвращение ссылки

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

// пример некорректного возвращения ссылки int& max(int a, int b) < if (a >b) return a; else return b; >

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

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

#include int& max(int&, int&); int main() < int n; int m; int result = max(n, m); std::cout // пример корректного возвращения ссылки int& max(int& a, int& b) < if (a >b) return a; else return b; >

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

#include const int& max(const int&, const int&); int main() < int n; int m; int result = max(n, m); std::cout // пример корректного возвращения ссылки const int& max(const int& a, const int& b) < if (a >b) return a; else return b; >

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

компилятором воспринимается как попытка вернуть локальную переменную? Я понимаю, что дело не в компиляторе, ошибка на самом деле есть.

94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Возврат указателя на массив из функции
Здравствуйте. Пытаюсь вернуть указатель на массив из функции. #include <iostream> using.

Возврат указателя на массив из функции
День добрый, коллеги по цеху. Не откажите в нужде java программисту в познаниях нативного кода.

Возврат указателя из функции с нужным типом
Как как мне получить из функции указатель нужного мне типа? Можно ли для этого использовать.

Возврат указателя
Написать функцию возвращающую ссылку на элемент глобального массива. #include <stdio> #include.

243 / 88 / 44
Регистрация: 30.12.2013
Сообщений: 316
Записей в блоге: 2
element - это локальный объект.
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045

Странный вопрос. Воспринимается как попытка вернуть указатель на локальную переменную, потому что element - локальная переменная. Как еще должен вести себя компилятор в данном случае?

Регистрация: 16.08.2020
Сообщений: 25

ЦитатаСообщение от kylroma Посмотреть сообщение

element - это локальный объект.

ЦитатаСообщение от valen10 Посмотреть сообщение

Странный вопрос.
Я - идиот, простите

Эксперт С++

8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30

ЦитатаСообщение от markmarks Посмотреть сообщение

Я - идиот, простите
Ох уж эта самокритика
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Возврат функцией указателя на функцию
Всем привет! У меня возникла такая проблема: класс имеет поле-указатель на функцию. В методе.

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

Возврат указателя на локальный объект
Доброго дня! Заинтересовал процесс возврата указателя на локальный объек, а именно: char* fun()

Возврат указателя на строку из фукнции
Снова я пришел к вам со строками. Читаю "Как программировать на С++" и там везде пишут про.

Visual c++ возврат указателя, return *char
есть класс journal, Я передаю в char *name значение "gfg", а возвращает от мне заименнованное.

Возврат указателя на внутренний объект класса
Добрый день! Имеется следующая структура: class A<>; class B : public A<>; class C

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

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