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는 상당히 잘 작동하지만, 이러한 목적을 위해 전문화된 구조물을 만드는 데는 약간의 정신적 간접비가 수반된다.
포인터를 함수 매개 변수로 사용하십시오.그런 다음 이 값을 사용하여 여러 값을 반환하십시오.
기능을 기준으로 매개 변수를 전달함.
예:
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
'programing' 카테고리의 다른 글
한 구조물을 다른 구조물에 복사 (0) | 2022.04.27 |
---|---|
상속과 구성의 차이 (0) | 2022.04.27 |
프로그래밍 방식으로 생성된 vuejs 구성 요소 인스턴스에 슬롯을 전달하는 방법 (0) | 2022.04.27 |
Vue 3 구성 요소 내부의 Vuex 4 상태 데이터를 다른 디스패치를 위한 페이로드로 사용하는 방법 (0) | 2022.04.27 |
계산된 속성을 사용할 때 $store 속성이 반응하지 않음(Vuex) (0) | 2022.04.26 |