如果我有一个函数可以返回int
类型的结果和string
类型的结果,我该如何从函数中同时返回它们?
据我所知,一个函数只能返回一种类型的值,这由函数名前面的类型决定。
如果我有一个函数可以返回int
类型的结果和string
类型的结果,我该如何从函数中同时返回它们?
据我所知,一个函数只能返回一种类型的值,这由函数名前面的类型决定。
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);
}
你选择使用哪一种取决于个人偏好,无论你更喜欢哪种语义。
getPair
再次进行了_取消引用_操作。根据您要做什么(OP 从未明确说明这是否真的是一个 C 问题),分配可能是一个问题,但在 C++ 领域通常不是问题(返回值优化可以节省所有这些),而在 C 领域中,数据复制通常会显式地进行(通过 strncpy
或其他方式)。 - Travis Gockel选项1
:声明一个包含整数和字符串的结构体并返回一个结构体变量。
struct foo {
int bar1;
char bar2[MAX];
};
struct foo fun() {
struct foo fooObj;
...
return fooObj;
}
选项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;
}
选项3
: 类似于选项2。您可以通过指针传递这两个参数,并从函数中返回空值:
void fun(char **param1,int *param2) {
strcpy(*param1,"....");
*param2 = /* some calculated value */
}
int fun(char *param, size_t len)
- Chris Lutzstrcpy
的方式。 - codaddictstruct result {
int a;
char *string;
}
在你的程序中,你必须为char *
分配空间。
由于你的结果类型之一是字符串(并且你使用的是 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);
一般而言,最好在调用函数中进行分配,而不是在函数内部进行分配,这样您就可以尽可能地针对不同的分配策略进行开放。
string
,所以可以安全地假设是C++... - Travis Gockel一种方法是使用宏。将以下内容放入头文件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)
我的 github 代码库 中提供了其他示例和基于堆栈的版本。
__typeof__
。 - M.M使用指针作为函数参数,然后使用它们来返回多个值。
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)
真让人抓狂! - Chris Lutzmain
应该返回一个状态码。在 *nix 中,通常将其声明为 int main(int argc, char *argv[])
,我相信 Windows 也有类似的约定。 - Duncan
std::string
类”,还是表示“我正在使用C语言,这是一个char *
指针或char[]
数组”? - Chris Lutz