programing

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

prostudy 2022. 4. 27. 21:34
반응형

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

결과를 생성하는 기능이 있는 경우int그리고 결과string함수에서 두 개를 모두 반환하려면 어떻게 해야 하는가?

내가 알 수 있는 한 나는 함수 이름 앞에 있는 종류에 의해 결정되는 한 가지만 반환할 수 있다.

무슨 말인지 모르겠다.string하지만 기억력을 관리한다고 가정해 볼게

다음과 같은 두 가지 해결책이 있다.

1: 반품 astruct네가 필요한 모든 타입을 포함하고 있어.

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

당신이 어떤 것을 선택하느냐는 주로 당신이 더 좋아하는 의미론들에 관한 개인적인 선호에 달려있다.

구조체를 생성하고 내부에 두 개의 값을 설정한 후 구조 변수를 반환하십시오.

struct result {
    int a;
    char *string;
}

공간을 할당해야 한다.char *네 프로그램에서 말이야

한 가지 접근법은 매크로를 사용하는 것이다.머리글 파일에 저장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)

이 솔루션은 가변 매크로 및 진술용 변수 선언에 C99 이상이 필요하기 때문에 휴대성이 떨어질 수 있다.하지만 여기에 올릴 만큼 재미있었던 것 같아.또 다른 문제는 컴파일러에게 잘못된 값을 할당하면 컴파일러가 경고를 하지 않기 때문에 주의해야 한다는 것이다.

추가 예제와 유니언을 사용하는 스택 기반 코드의 버전을 내 github 저장소에서 사용할 수 있다.

결과 유형 중 하나가 문자열이기 때문에(그리고 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);

일반적으로, 서로 다른 할당 전략에 대해 가능한 한 개방적일 수 있도록, 함수 자체의 내부가 아닌 호출 함수의 할당을 선호한다.

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. 포인터로 반환 값을 전달하고 함수 내에서 수정하십시오.당신은 당신의 기능을 무효라고 선언하지만, 그것은 포인터로 전달된 값을 통해 되돌아오고 있다.
  2. 반환 값을 집계하는 구조를 정의하십시오.

1번은 수익률이 너무 많으면 지루해질 수 있지만, 무슨 일이 일어나고 있는지 좀 더 분명하다고 생각한다.이 경우, 옵션 #2는 상당히 잘 작동하지만, 이러한 목적을 위해 전문화된 구조물을 만드는 데는 약간의 정신적 간접비가 수반된다.

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

기능을 기준으로 매개 변수를 전달함.

예:

 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.
}

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

반응형