Возврат нескольких значений из функции в C
В этом посте будет обсуждаться, как вернуть несколько значений из функции в C.
Мы знаем, что синтаксис функций в C не позволяет нам возвращать несколько значений. Но программистам часто нужно возвращать из функции несколько значений. К счастью, в C есть несколько обходных путей для возврата нескольких значений.
1. Указатели в C
Мы можем использовать указатели в C для возврата более одного значения из функции, передавая указатели в качестве параметров функции и используя их для установки нескольких значений, которые затем будут видны в вызывающей функции.
результат:
a = 10, b = 20, c = A
2. Структуры в C
Мы также можем использовать структуры в C, чтобы возвращать более одного значения из функции. Мы знаем, что структура — это определяемый пользователем тип данных в C, который может содержать несколько типов данных одного или разных типов.
Идея состоит в том, чтобы создать структуру, содержащую в качестве членов все необходимые типы данных, и вернуть эту структуру из нашей функции. Затем мы можем получить нужные значения из структуры внутри нашей вызывающей функции.
результат:
a = 10, b = 20, c = A
3. Массив
Мы видели, как возвращать значения различных типов данных из функции с помощью указателей и распорок. Теперь, если все значения имеют один и тот же тип данных, мы можем инкапсулировать значения в массив и вернуть этот массив, как показано ниже:
результат:
a = 10, b = 20, c = 30
Мы не должны использовать этот подход, так как информация о переменной не передается вызывающей функции. Например, мы используем индекс массива для получения значений наших переменных. Также обратите внимание, что мы должны динамически размещать массив в куче. Если мы используем статический массив, он перестает существовать, когда мы выходим из функции, и доступ к нему внутри вызывающей функции приведет к неопределенному поведению.
Это все о возврате нескольких значений из реализации функции на C.
Также см:
Оценить этот пост
Средний рейтинг 4.69 /5. Подсчет голосов: 49
Голосов пока нет! Будьте первым, кто оценит этот пост.
Сожалеем, что этот пост не оказался для вас полезным!
Расскажите, как мы можем улучшить этот пост?
Спасибо за чтение.
Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.
Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования
Как вернуть несколько значений из функции в C#
![]()
Для того чтобы вернуть несколько значений из функции, нужно объявить необходимые параметры с модификаторами out. Например.
![]()
В версиях C# c 4 по 6 включительно, лучшими вариантами вернуть из функции(метода вернее), являлись возвращение кортежа Tuple<> или создание класса\структуры с нужными свойствами. Вариант с out-параметрами, хуже, т.к. немного выбивается из основных парадигм применяемых при разработке на C#, и был встроен скорее для поддержки импорта нативных функций.
C++
Возвращение нескольких значений из функции
Существует много ситуаций, когда полезно возвращать несколько значений из функции: например, если вы хотите ввести элемент и вернуть цену и количество на складе, эта функция может быть полезна. Есть много способов сделать это на C ++, и большинство из них связано с STL. Однако, если вы хотите избежать STL по какой-то причине, есть еще несколько способов сделать это, включая structs/classes и arrays .
Использование выходных параметров
Параметры могут использоваться для возврата одного или нескольких значений; эти параметры должны быть const указателями или ссылками.
Некоторые библиотеки или фреймворки используют пустой 'OUT' #define чтобы сделать его совершенно очевидным, какие параметры являются выходными параметрами в сигнатуре функции. Это не имеет никакого функционального воздействия и будет скомпилировано, но делает подпись функции более понятной;
Использование std :: tuple
Тип std::tuple может связывать любое количество значений, потенциально включающих значения разных типов, в один возвращаемый объект:
В C ++ 17 можно использовать список упрощенных инициализаторов:
Получение значений из возвращаемого tuple может быть громоздким, требуя использования функции std::get template:
Если типы могут быть объявлены до возвращения функции, то std::tie можно использовать для распаковки tuple в существующие переменные:
Если одно из возвращаемых значений не требуется, можно использовать std::ignore :
Структурные привязки можно использовать, чтобы избежать std::tie :
Если вы хотите вернуть кортеж ссылок lvalue вместо кортежа значений, используйте std::tie вместо std::make_tuple .
В некоторых редких случаях вы будете использовать std::forward_as_tuple вместо std::tie ; будьте осторожны, если вы это сделаете, поскольку временные периоды могут длиться недостаточно долго, чтобы их можно было потреблять.
Использование std :: array
Контейнер std::array может связывать фиксированное число возвращаемых значений. Этот номер должен быть известен во время компиляции, и все возвращаемые значения должны быть одного типа:
Это заменяет c массивами стиля формы int bar[4] . Преимущество состоит в том, что теперь можно использовать различные функции std c++ . Он также содержит полезные функции — членов , как at котором является безопасной функцией доступа члена с связанной проверкой, и size , который позволяет вернуть размер массива без расчета.
Использование std :: pair
Структурный шаблон std::pair может связывать ровно два возвращаемых значения любых двух типов:
С C ++ 11 или более поздней std::make_pair вместо std::make_pair можно использовать список инициализаторов:
Отдельные значения возвращенной std::pair могут быть получены с использованием first и second объектов-членов пары:
Использование структуры
struct можно использовать для объединения нескольких возвращаемых значений:
Вместо назначения отдельным полям конструктор может использоваться для упрощения построения возвращаемых значений:
Отдельные результаты, возвращаемые функцией foo() могут быть получены путем доступа к переменным-членам struct calc :
Выход:
Примечание. При использовании struct возвращаемые значения группируются вместе в одном объекте и доступны с использованием значимых имен. Это также помогает уменьшить количество посторонних переменных, созданных в области возвращаемых значений.
Чтобы распаковать struct возвращаемую функцией, можно использовать структурированные привязки . Это приводит к тому, что параметры вывода на четной основе имеют параметры:
Результат этого кода идентичен выходу. struct по — прежнему используется для возврата значения из функции. Это позволяет вам обрабатывать поля отдельно.
Структурированные привязки
В C ++ 17 реализованы структурированные привязки, что упрощает работу с несколькими типами возвращаемых данных, так как вам не нужно полагаться на std::tie() или выполнять ручную распаковку:
Структурированные привязки могут использоваться по умолчанию с помощью std::pair , std::tuple и любого типа, чьи нестатические члены данных являются либо публичными прямыми членами, либо членами недвусмысленного базового класса:
Если вы сделаете свой тип «tuple-like», он также автоматически будет работать с вашим типом. Кортеж, как тип с соответствующим tuple_size , tuple_element и get написано:
теперь это работает:
Использование функции Object Consumer
Мы можем предоставить потребителю, который будет вызываться с несколькими соответствующими значениями:
Вы можете адаптировать функцию, возвращающую кортеж, в функцию продолжения прохождения через:
причем более сложные версии записываются на C ++ 14 или C ++ 11.
Использование std :: vector
std::vector может быть полезен для возврата динамического числа переменных того же типа. Следующий пример использует int как тип данных, но std::vector может содержать любой тип, который тривиально можно копировать:
Использование выходного итератора
Несколько значений одного и того же типа могут быть возвращены путем передачи выходного итератора в функцию. Это особенно характерно для общих функций (таких как алгоритмы стандартной библиотеки).
вернуть Несколько значений из функции в C
Нужно возвратить из функции значения 2х переменных. На ум приходит только идея сделать массив с этими значениями и через return выдать указатель на него. Но может есть другой способ?

Re: вернуть Несколько значений из функции в C
Не нравится мне твоё "сделать массив", сдаётся мне что ты собрался ссылку на локальный массив возвращать. 🙂 Очень не рекомендую. 🙂
Вообще обычно в таких случаях функции передают указатель на массив или структуру, в которую она пишет результаты. А возвращает она в таком случае просто код завершения (типа успешно/неуспешно). См., например, man 2 fstat.

Re: вернуть Несколько значений из функции в C
Re: вернуть Несколько значений из функции в C

Re: вернуть Несколько значений из функции в C

Re: вернуть Несколько значений из функции в C
>> Выделять память внутри функции считается не оч. правильным путём, насколько я понимаю. Так что наиболее правильным является передача функции указателя на структуру (или массив):
не спорю, попросили привести пример, мну привел то что первое в голову пришло )

Re: вернуть Несколько значений из функции в C
>не спорю, попросили привести пример, мну привел то что первое в голову пришло )
Да не, никаких претензий. Сам так иногда делаю. Более того, по-моему, в каких-то стандартных вызовах было нечто подобное.
Я так понимаю, что логика состоит в том, что выделением памяти и её освобождением должны быть в логически эквивалентных местах.
То есть, например, в случае наличия функций retval2 *alloc_s1() и int free_s2(retval2 *r), всё уже хорошо. Вот и пример, где это может быть оправдано.
Кстати, всё это уже начинает смахивать на ООП.

Re: вернуть Несколько значений из функции в C
таки ООП это парадигма программирования и не зависит от конкретной реализации в ЯВУ

Re: вернуть Несколько значений из функции в C
Re: вернуть Несколько значений из функции в C
>>Так можно делать только если массив статический:
>Только надо быть очень аккуратным: при повторном вызове будет возвращён >тот же указатель.
Еще это несколько не thread-safe
Re: вернуть Несколько значений из функции в C

Re: вернуть Несколько значений из функции в C
Ну и нахрена звать malloc без необходимости? Если только чтоб выпендриться.

Re: вернуть Несколько значений из функции в C
> Так можно делать только если массив статический:
ужоснах, не слушайте его, дети. 🙂 функция станет нереентрабельной, приглашаю всех в гугль на тему чем это грозит.
Re: вернуть Несколько значений из функции в C
> ужоснах, не слушайте его, дети. 🙂 функция станет нереентрабельной, приглашаю всех в гугль на тему чем это грозит.
Конечно так делать не следует, хотя и возможно. Вобщем я сказал "can", а ты имел ввиду "may" 🙂
Блин, простой вопрос растянули уже на чертову дюжину постов. Короче, vdm, передавай в функцию адрес структуры с двумя полями и не парься. Все остальное грязный хак.

Re: вернуть Несколько значений из функции в C
Согласен, все посты в этой теме, кроме первого, моего, — лишние. 🙂

Re: вернуть Несколько значений из функции в C
ув. тов. Teak прочтите пост выше.
Re: вернуть Несколько значений из функции в C
> ув. тов. Teak прочтите пост выше.
Не, Ex, извини, но ты там фигню написал. Заморачиваться со структурой в функции стоит только если ты ее всю будешь возращать (структурка небольшая). А создавать ее динамически, а потом возвращать указатель, имхо хреновая идея. Кто-то использующий твою функцию должен знать и помнить о том, что ему где-то free надо втыкать, лишний, тяжелый malloc, и ради чего все?
Re: вернуть Несколько значений из функции в C
> Согласен, все посты в этой теме, кроме первого, моего, — лишние. 🙂
ты не указал решение с возвратом структуры. Оно непопулярно, потому что этого не было в ранних компиляторах и про это не написано в К&Р Но для 2-х полей оно оптимально
Re: вернуть Несколько значений из функции в C
> Оно непопулярно, потому что этого не было в ранних компиляторах и про это не написано в К&Р
Вот хохма на эту тему, совершенно случайно наткнулся:
2.2: I heard that structures could be assigned to variables and passed to and from functions, but K&R I says not.
K&R I was wrong; they hadn’t actually learned C very well before writing the book. Later, Ritchie got a job at Bell Labs, and worked closely with the authors of C, allowing the 2nd edition of the book to be much more accurate. (Kernighan already worked at Bell Labs, as a video game developer.)