Как вернуть указатель из функции 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».

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

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

Рассмотрим простейший пример:

#include void goodmorning(); void goodevening(); void(*message(unsigned))(); int main() < void(*action)(); // указатель на выбранную функцию // выполняем полученную функцию action(); // Good Morning! action = message(16); // получаем новую функцию action(); // Good Evening! > void(*message(unsigned hour))() < if (hour >15) return goodevening; else return goodmorning; > void goodmorning() < std::cout void goodevening()

Здесь определена функция message, которая в зависимости от переданного числа возвращает одну из двух функций goodmorning или goodevening. Рассмотрим объявление функции message:

void(*message(unsigned hour))()

Вначале указан тип, который возвращается функцией, которая возвращается из message, то есть тип void (функции goodmorning и goodevening имеют тип void). Далее идет в скобках имя функции со списком параметров, то есть функция message принимает один параметр типа unsigned int : (*message(unsigned hour)) . После этого отдельно в скобках идет спецификация параметров функции, которая будет возвращаться из message. Поскольку функции goodmorning и goodevening не принимают никаких параметров, то указываются пустые скобки.

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

Для получения указателя на функцию определяем переменную action:

void(*action)();

Эта переменная представляет указатель на функцию, которая не принимает параметров и имеет в качестве возвращаемого типа тип void, то есть она соответствует функциям goodmorning и goodevening.

Затем вызываем функцию message и получаем указатель на функцию в переменную action:

action = message(16);

Далее, используя указатель action, вызываем полученную функцию:

action();

Поскольку в функцию message передается число 16, то она будет возвращать указатель на функцию goodevening, поэтому при ее вызове на консоль будет выведено сообщение «Good Evening!»

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

#include int add(int, int); int subtract(int, int); int multiply(int, int); int(*select(int))(int, int); int main() < int(*action)(int, int) ; // получаем указатель на функцию add std::cout int(*select(int choice))(int, int) < // возвращаем нужную функцию в зависимости от choice switch (choice) < case 2: return subtract; case 3: return multiply; default: return add; >> int add(int x, int y) < return x + y; >int subtract(int x, int y) < return x - y; >int multiply(int x, int y)

В данной программе мы предполагаем, что пользователь должен выбрать для выполнения одну из трех функций: add, subtract, multiply. И выбранная функция будет выполнять определенное действие над двумя числами x и y.

Сам выбор происходит в функции select() . Она получает условный номер функции и возвращает указатель на функцию — по сути выбранную функцию.

Все выбираемые функции имеют прототип вида:

int add(int, int);

И прототип функции select должен соответствовать этому прототипу:

int (*select(int))(int, int)

То есть в начале идет тип — возвращаемый тип указателя на функцию, то есть int. Затем идет определение самой функции select — ее название со списком параметров помещается в скобках — (*select(int)) . Затем идет спецификация параметров функции, на которую определяется указатель. Так как функции add, subtract и multiply принимают два значения типа int, то соответственно спецификация параметров выглядит следующим образом (int, int) .

Для выбора нужной функции в select применяется конструкция switch-case:

int(*select(int choice))(int, int) < // возвращаем нужную функцию в зависимости от choice switch (choice) < case 2: return subtract; case 3: return multiply; default: return add; >>

В функции main() вызываем функцию select, передавая в нее определенное число и получая в качестве результата указатель на функцию:

int(*action)(int, int) ; // получаем указатель на функцию add

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

std::cout 

В примере выше сделано довольно просто - какое-бы число не будет передано в функцию select, она всегда возвратит указатель на некоторую функцию. Однако мы можем ограничить выбор:

#include int add(int, int); int subtract(int, int); int multiply(int, int); int(*select(int))(int, int); int main() < int(*action)(int, int) ; // получаем указатель на функцию if(action) // если не равно nullptr < std::cout else < std::cout > int(*select(int choice))(int, int) < int (*actions[])(int x, int y)< add, subtract, multiply >; // возвращаем нужную функцию в зависимости от choice // возвращаем нужную функцию if (choice >0 && choice <4) return actions[choice - 1]; else return nullptr; >int add(int x, int y) < return x + y; >int subtract(int x, int y) int multiply(int x, int y)

В данном случае все доступные для выбора функции хранятся в массиве actions, который представляет массив указателей на функции. Если передан номер 1, 2 или 3, то возвращаем из этого массива определенную функцию. Если переданный номер функции представляет другое число, то возвращаем значение nullptr :

if (choice >0 && choice<4) return actions[choice - 1]; else return nullptr;

Поскольку возвращается nullptr, то перед выполнением полученной функции указатель надо проверить на nullptr:

int(*action)(int, int) ; // получаем указатель на функцию if(action) // если не равно nullptr < std::cout else

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

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

int *byThress(int i); int _tmain(int argc, _TCHAR* argv[]) < int i,k; int *p; cout > i; cout int *byThress(int i) < int k ; int *p; int mas[5]; mas[0] = i; for(k=1;k<5;k++) mas[k]=mas[k-1]+3; return mas;
Neolit1819
Посмотреть профиль
Найти ещё сообщения от Neolit1819

Лжец и смутьян
Форумчанин
Регистрация: 03.04.2009
Сообщений: 194

const stdsize = 5; const stdinc = 3; void GenArray(int, int, int, int*); int main() < int v; cout > v; cout void GenArray(int value, int inc, int size, int* result)

Помогли тебе - помоги другому.
Форумчанин
Регистрация: 29.09.2010
Сообщений: 636
ну как вариант

int *GenArray(int value, int inc, int size, int* result) . return result;

оно и изменит массив и в добавок и вернет указатель.
многие стандартные функции так поступают для удобства, например memmove, strcpy.

Пользователь
Регистрация: 28.03.2011
Сообщений: 51
Сообщение от Alt

const stdsize = 5; const stdinc = 3; void GenArray(int, int, int, int*); int main() < int v; cout > v; cout void GenArray(int value, int inc, int size, int* result)

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

Последний раз редактировалось Neolit1819; 28.03.2011 в 12:56 .

Neolit1819
Посмотреть профиль
Найти ещё сообщения от Neolit1819

Вернуть указатель на массив из функции и продолжить работу с этим массивом в main()

Author24 — интернет-сервис помощи студентам

Функция создает массив или изменяет его уже готовый. Главное - готовый массив передать в main и продолжить работу с ним уже в main. С помощью указателя? И как, например, уже в main вывести массив на экран?

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

Как в функции вернуть значение, а потом продолжить работу этой функции?
Есть функция main, которая возвращает определенное значение. Это значение должно вернутся в течении.

Продолжить работу после выполнения Main
Надо сделать так чтобы приложения не заканчивала выполнения после закачивания Main

Вернуть указатель на массив из функции
Дан массив из 20 элементов, который заполняется в функции, причем заполнение можно прервать.

Как вернуть из функции указатель на массив элементов класса
Здравствуйте! Возникла такая проблема. Есть класс, созданный мной. Функция формирует массив.

1901 / 1323 / 963
Регистрация: 12.02.2013
Сообщений: 2,164

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
#include #include #include //----------------------------------------------------------------------------- int Random(int min, int max) { return (rand() % (max - min + 1) + min); } //----------------------------------------------------------------------------- // Функция заполняет массив случайными числами int* FillArray(int array[], size_t size, int min, int max) { size_t i; for (i = 0; i  size; ++i) { array[i] = Random(min, max); } return array; } //----------------------------------------------------------------------------- // Функция выводит массив на экран void Print(int array[], size_t size) { size_t i; for (i = 0; i  size; ++i) { printf("%d ", array[i]); } printf("\n"); } //----------------------------------------------------------------------------- int main() { srand(time(NULL)); int array[10]; FillArray(array, 10, -5, 5); Print(array, 10); return 0; }

419 / 418 / 167
Регистрация: 28.11.2010
Сообщений: 1,183

Лучший ответ

Сообщение было отмечено Sammi2186 как решение

Решение

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
#include #include #define RND(A, B) ((A) + rand() % ((B) - (A))) int *alloc_vect(size_t size) { size_t i = 0; int * r = (int*) calloc(size, sizeof(int)); if (r == NULL ) { printf("Can't allocate memory"); exit(1); } else { for (i = 0; i  size; ++i) r[i] = RND(5,10); } return r; } int dealloc_vect(int * v, size_t size) { if (v != NULL ) { free(v); return 0; } else { printf("Error. Vector is empty"); return 1; } } void print(int *v, size_t size) { size_t i = 0; for (i = 0; i  size; ++i) printf("%4d", v[i]); } ; int main() { size_t s; scanf("%zu", &s); int *vector = alloc_vect(s); print(vector, s); dealloc_vect(vector, s); return 0; }

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

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

Объяснить работу функции, возвращающей указатель на указатель на char
Добрый день! Сможете объяснить что означает запись char **InputFile(int &strings);? Почему.

Работа с файлом (передать указатель на файл в функцию, вернуть указатель на файл из функции)
Подскажите как передать указатель на файл в функцию, как вернуть указатель на файл из функции. .

Вернуть значение из функции summa в функцию main
//Я только начал учить функции, и столкнулся с такой проблемой - //пример из учебника не.

Не могу через указатель на двумерный массив вернуть все значения в другой массив
Не могу через указатель на двумерный массив вернуть все значения в другой массив возвращается.

Или воспользуйтесь поиском по форуму:

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

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