Как вернуть два значения из функции?

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

Предположим, что я передал два значения функции 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, &quot)

Еще одна вещь, которую вы можете сделать, это упаковать ваши данные в структуру

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);