Если у меня есть функция, которая дает результат int и результат string, как мне вернуть их как из функции?
Насколько я могу судить, я могу только вернуть одно, как определено типом, предшествующим имени функции.
Если у меня есть функция, которая дает результат int и результат string, как мне вернуть их как из функции?
Насколько я могу судить, я могу только вернуть одно, как определено типом, предшествующим имени функции.
Я не знаю, что такое string, но я предполагаю, что он управляет собственной памятью.
У вас есть два решения:
1: Верните a struct, который содержит все типы, которые вам нужны.
struct Tuple {
    int a;
    string b;
};
struct Tuple getPair() {
    Tuple r = { 1, getString() };
    return r;
}
void foo() {
    struct Tuple t = getPair();
}
2: Используйте указатели для передачи значений.
void getPair(int* a, string* b) {
    // Check that these are not pointing to NULL
    assert(a);
    assert(b);
    *a = 1;
    *b = getString();
}
void foo() {
    int a, b;
    getPair(&a, &b);
}
Какой из них вы предпочитаете использовать, во многом зависит от личных предпочтений относительно любой семантики, которая вам больше нравится.
 Option 1: объявить структуру с int и строкой и вернуть структурную переменную.
struct foo {    
 int bar1;
 char bar2[MAX];
};
struct foo fun() {
 struct foo fooObj;
 ...
 return fooObj;
}
  Option 2: вы можете передать один из двух указателей через указатель и внести изменения в фактический параметр через указатель и вернуть другой как обычно:
int fun(char **param) {
 int bar;
 ...
 strcpy(*param,"....");
 return bar;
}
или же
 char* fun(int *param) {
 char *str = /* malloc suitably.*/
 ...
 strcpy(str,"....");
 *param = /* some value */
 return str;
}
  Option 3: аналогично опции 2. Вы можете передавать оба указателя и ничего не возвращать из функции:
void fun(char **param1,int *param2) {
 strcpy(*param1,"....");
 *param2 = /* some calculated value */
}
		Создайте структуру и установите два значения внутри и верните структурную переменную.
struct result {
    int a;
    char *string;
}
Вы должны выделить место для char * в своей программе.
Два разных подхода:
Я думаю, что №1 немного более очевиден в том, что происходит, хотя он может утомиться, если у вас слишком много возвращаемых значений. В этом случае вариант № 2 работает достаточно хорошо, хотя некоторые интеллектуальные накладные расходы связаны с созданием специализированных структур для этой цели.
Поскольку один из ваших типов результатов является строкой (и вы используете C, а не С++), я рекомендую передавать указатели в качестве выходных параметров. Использование:
void foo(int *a, char *s, int size);
и назовите его следующим образом:
int a;
char *s = (char *)malloc(100); /* I never know how much to allocate :) */
foo(&a, s, 100);
В общем, предпочитайте делать выделение в вызывающей функции, а не внутри самой функции, чтобы вы могли быть как можно более открытыми для разных стратегий распределения.
Используйте указатели в качестве параметров вашей функции. Затем используйте их для возврата нескольких значений.
Передача параметров по ссылке на функцию.
Примеры:
 void incInt(int *y)
 {
     (*y)++;  // Increase the value of 'x', in main, by one.
 }
Также, используя глобальные переменные, но не рекомендуется.
Пример:
int a=0;
void main(void)
{
    //Anything you want to code.
}
		Один из подходов - использование макросов. Поместите это в файл заголовка multitype.h
#include <stdlib.h>
/* ============================= HELPER MACROS ============================= */
/* __typeof__(V) abbreviation */
#define TOF(V) __typeof__(V)
/* Expand variables list to list of typeof and variable names */
#define TO3(_0,_1,_2,_3) TOF(_0) v0; TOF(_1) v1; TOF(_2) v2; TOF(_3) v3;
#define TO2(_0,_1,_2)    TOF(_0) v0; TOF(_1) v1; TOF(_2) v2;
#define TO1(_0,_1)       TOF(_0) v0; TOF(_1) v1;
#define TO0(_0)          TOF(_0) v0;
#define TO_(_0,_1,_2,_3,TO_MACRO,...) TO_MACRO
#define TO(...) TO_(__VA_ARGS__,TO3,TO2,TO1,TO0)(__VA_ARGS__)
/* Assign to multitype */
#define MTA3(_0,_1,_2,_3) _0 = mtr.v0; _1 = mtr.v1; _2 = mtr.v2; _3 = mtr.v3;
#define MTA2(_0,_1,_2)    _0 = mtr.v0; _1 = mtr.v1; _2 = mtr.v2;
#define MTA1(_0,_1)       _0 = mtr.v0; _1 = mtr.v1;
#define MTA0(_0)          _0 = mtr.v0;
#define MTA_(_0,_1,_2,_3,MTA_MACRO,...) MTA_MACRO
#define MTA(...) MTA_(__VA_ARGS__,MTA3,MTA2,MTA1,MTA0)(__VA_ARGS__)
/* Return multitype if multiple arguments, return normally if only one */
#define MTR1(...) {                                                           \
    typedef struct mtr_s {                                                    \
      TO(__VA_ARGS__)                                                         \
    } mtr_t;                                                                  \
    mtr_t *mtr = malloc(sizeof(mtr_t));                                       \
    *mtr = (mtr_t){__VA_ARGS__};                                              \
    return mtr;                                                               \
  }
#define MTR0(_0) return(_0)
#define MTR_(_0,_1,_2,_3,MTR_MACRO,...) MTR_MACRO
/* ============================== API MACROS =============================== */
/* Declare return type before function */
typedef void* multitype;
#define multitype(...) multitype
/* Assign return values to variables */
#define let(...)                                                              \
  for(int mti = 0; !mti;)                                                     \
    for(multitype mt; mti < 2; mti++)                                         \
      if(mti) {                                                               \
        typedef struct mtr_s {                                                \
          TO(__VA_ARGS__)                                                     \
        } mtr_t;                                                              \
        mtr_t mtr = *(mtr_t*)mt;                                              \
        MTA(__VA_ARGS__)                                                      \
        free(mt);                                                             \
      } else                                                                  \
        mt
/* Return */
#define RETURN(...) MTR_(__VA_ARGS__,MTR1,MTR1,MTR1,MTR0)(__VA_ARGS__)
Это позволяет возвращать до четырех переменных из функции и назначать их до четырех переменных. Например, вы можете использовать их следующим образом:
multitype (int,float,double) fun() {
    int a = 55;
    float b = 3.9;
    double c = 24.15;
    RETURN (a,b,c);
}
int main(int argc, char *argv[]) {
    int x;
    float y;
    double z;
    let (x,y,z) = fun();
    printf("(%d, %f, %g\n)", x, y, z);
    return 0;
}
Это то, что он печатает:
(55, 3.9, 24.15)
Решение может быть не таким портативным, потому что для него требуется C99 или более поздняя версия для переменных переменных и объявлений переменных for-statement. Но я думаю, что было достаточно интересно опубликовать здесь. Другая проблема заключается в том, что компилятор не предупредит вас, если вы присвоите им неправильные значения, поэтому вы должны быть осторожны.
Дополнительные примеры и сводная версия кода с использованием объединений доступны в моем репозитории github.
Этот подход может быть упрощен, если вы используете С++ 11 и выше. Вы можете использовать функцию std :: make_tuple()
#include <tuple>
auto Foo(type input){
.....
......
return std::make_tuple(output1, output2, output3);
}
		Привет, я могу вернуть 2 значения с помощью указателей в C.