programing tip

C의 함수에서 여러 값을 반환하려면 어떻게해야합니까?

itbloger 2020. 10. 10. 09:40
반응형

C의 함수에서 여러 값을 반환하려면 어떻게해야합니까?


결과 int결과를 생성하는 함수가있는 경우 함수 string에서 둘 다 반환하려면 어떻게해야합니까?

내가 알 수있는 한, 함수 이름 앞의 유형에 의해 결정된대로 한 가지만 반환 할 수 있습니다.


나는 당신 string무엇인지 모르지만 그것이 자체 메모리를 관리한다고 가정 할 것입니다.

두 가지 솔루션이 있습니다.

1 : struct필요한 모든 유형을 포함 하는 a 반환 합니다.

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 */
}

두 가지 접근 방식 :

  1. 반환 값을 포인터로 전달하고 함수 내에서 수정하십시오. 함수를 void로 선언하지만 포인터로 전달 된 값을 통해 반환됩니다.
  2. 반환 값을 집계하는 구조체를 정의합니다.

반환 값이 너무 많으면 지루할 수 있지만 # 1은 무슨 일이 일어나고 있는지에 대해 조금 더 분명하다고 생각합니다. 이 경우 옵션 # 2는이 목적을위한 특수 구조체를 만드는 데 정신적 오버 헤드가 있지만 꽤 잘 작동합니다.


결과 유형 중 하나가 문자열 (그리고 C ++이 아닌 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);

일반적으로 함수 자체가 아닌 호출 함수 에서 할당을 수행하는 것을 선호 하므로 다른 할당 전략에 대해 최대한 개방 될 수 있습니다.


구조체를 만들고 내부에 두 개의 값을 설정하고 구조체 변수를 반환합니다.

struct result {
    int a;
    char *string;
}

char *프로그램에서에 대한 공간을 할당 해야합니다.


함수 매개 변수로 포인터를 사용하십시오. 그런 다음이를 사용하여 여러 값을 반환합니다.


함수에 대한 참조로 매개 변수를 전달합니다.

예 :

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

이를 통해 함수에서 최대 4 개의 변수를 반환하고 최대 4 개의 변수에 할당 할 수 있습니다. 예를 들어 다음과 같이 사용할 수 있습니다.

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)

The solution may not be as portable because it requires C99 or later for variadic macros and for-statement variable declarations. But I think it was interesting enough to post here. Another issue is that the compiler will not warn you if you assign them the wrong values, so you have to be careful.

Additional examples, and a stack-based version of the code using unions, are available at my github repository.

참고URL : https://stackoverflow.com/questions/2620146/how-do-i-return-multiple-values-from-a-function-in-c

반응형