결과 int
와 결과를 생성하는 함수가있는 경우 함수 string
에서 둘 다 반환하려면 어떻게해야합니까?
내가 알 수있는 한, 함수 이름 앞의 유형에 의해 결정된대로 한 가지만 반환 할 수 있습니다.
결과 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);
}
어떤 것을 사용하기로 선택하는지는 주로 당신이 더 좋아하는 의미에 대한 개인적인 선호도에 달려 있습니다.
char *
및 a size_t
로 길이 로 전달합니다 NULL
.
getPair
한 후 역 참조 . 수행중인 작업 (실제로 C 질문 인 경우 OP는 명확하지 않음)에 따라 할당이 문제가 될 수 있지만 일반적으로 C ++ 영역 (반환 값 최적화는이 모든 것을 저장함)과 C 영역에서 데이터가 아닙니다. 복사본은 일반적으로 명시 적으로 발생합니다 ( strncpy
또는 무엇이든).
Option 1
: int 및 string을 사용하여 구조체를 선언하고 구조체 변수를 반환합니다.
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 */
}
int fun(char *param, size_t len)
strcpy
예를 들어 우리가 사용하는 것과 비슷한 것 입니다.
결과 유형 중 하나가 문자열 (그리고 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);
일반적으로 함수 자체가 아닌 호출 함수 에서 할당을 수행하는 것을 선호 하므로 다른 할당 전략에 대해 최대한 개방 될 수 있습니다.
두 가지 접근 방식 :
반환 값이 너무 많으면 지루할 수 있지만 # 1은 무슨 일이 일어나고 있는지에 대해 조금 더 분명하다고 생각합니다. 이 경우 옵션 # 2는이 목적을위한 특수 구조체를 만드는 데 정신적 오버 헤드가 있지만 꽤 잘 작동합니다.
string
, 가정 안전 할 수있는 C ++ ...
함수에 대한 참조로 매개 변수를 전달합니다.
예 :
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.
}
void main(void)
오, 어떻게 화상!
main
상태 코드를 반환해야합니다. * nix에서는으로 선언하는 것이 더 일반적 int main(int argc, char *argv[])
이며 Windows에는 유사한 규칙이 있다고 생각합니다.
한 가지 방법은 매크로를 사용하는 것입니다. 이것을 헤더 파일에 넣으십시오.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)
가변 매크로 및 for-statement 변수 선언에 C99 이상이 필요하기 때문에 솔루션은 이식성이 떨어질 수 있습니다. 하지만 여기에 게시하는 것이 충분히 흥미 롭다고 생각합니다. 또 다른 문제는 잘못된 값을 할당하면 컴파일러가 경고하지 않으므로주의해야합니다.
추가 예제와 공용체를 사용하는 코드의 스택 기반 버전은 내 github 저장소 에서 사용할 수 있습니다 .
__typeof__
string
할 당신은 "나는 C를 사용하고 ++이이 의미std::string
클래스"또는 "나는 C를 사용하고 있는데 이것은이다char *
포인터 나char[]
배열입니다."