Как вернуть два значения из функции?
Возможный дубликат:
возвращает несколько значений из функции
Предположим, что я передал два значения функции iCalculate(int x, int y)
, и этот iCalculate
возвращает два значения. Это следующие: -
Теперь, как я должен возвращать вышеуказанные два значения одновременно с одной и той же функцией?
Мой подход: -
int* iCalculate(int x,int y){
int temp[2];
temp[0] = x*y;
temp[1] = x/y;
return temp;
}
Ответы
Ответ 1
возвращающий адрес первого элемента локального массива, имеет поведение undefined (по крайней мере, разыменование его позже).
Вы можете использовать выходные параметры, то есть передать два указателя и установить значения внутри
void Calculate(int x, int y, int* prod, int* quot)
{
*prod = x*y;
*quot = x/y;
}
использование:
int x = 10,y = 2, prod, quot;
Calculate(x, y, &prod, ")
Еще одна вещь, которую вы можете сделать, это упаковать ваши данные в структуру
typedef struct
{
int prod;
int quot;
} product_and_quot;
product_and_quot Calculate(int x, int y)
{
product_and_quot p = {x*y, x/y};
return p;
}
Ответ 2
Это не сработает, так как вы возвращаете указатель на временный массив, который остановится на время возврата функции.
Вместо этого определите
typedef struct { int first, second; } IntPair;
и вернуть объект этого типа.
(Это то, что делают стандартные функции библиотеки div
и ldiv
, за исключением того, что они вызывают тип по-разному.)
Ответ 3
Ваш подход ошибочен, temp
выходит за рамки/больше не существует, когда функция functon iCalculate
завершена. Поэтому вы не должны возвращать адрес temp
. Это будет обращение за пределы области/больше не существует переменной. Доступ к этому адресу означает поведение undefined.
Вы можете использовать этот подход:
void iCalculate(int x,int y,int *mult,int *divi){
*mult = x*y;
*divi = x/y;
}
или вы можете использовать другой подход:
typedef struct{
int mul, divi;
} TResult;
TResult iCalculate(int x,int y){
TResult res;
res.mul = x*y;
res.divi = x/y;
return res;
}
или:
void iCalculate(int x,int y,TResult *res){
res->mul = x*y;
res->divi = x/y;
}
Предлагаю первый подход. Я думаю, что слишком сложно создать новое определение структуры только для того, чтобы обернуть 2 несвязанных значения вместе.
Ответ 4
То, как вы это сделали, неверно, так как int temp[2]
исчезает после возвращения функции, поэтому у вызывающего есть указатель "свисающий". Вы должны добавить static
. Другой способ, вероятно, лучше, чтобы позволить вызывающему абоненту пройти, где он хочет, чтобы результат был сохранен, например.
void iCalc(int x, int y, int *rp, int *rq)
{
// check if rp and rq are NULL, if so, returns
*rp = x*y;
*rq = x/y; // y != 0, and this will truncate of course.
}
и вызывающий абонент сделает что-то вроде
int res[2];
iCalc(x, y, res, res+1);
или аналогичный.
Ответ 5
Ваш подход не был настолько неправильным, вы можете вернуть адрес таблицы следующим образом:
int *iCalculate(int x,int y){
int *temp=malloc(sizeof(int)*2);
temp[0]=x*y;
temp[1]=x/y;
return temp;
}
Не забывайте освобождать память:
int *result;
result=iCalculate(10,7);
printf("%d %d\n",result[0],result[1]);
free(result);