如果我有一个产生结果int
和结果的函数string
,如何从一个函数中返回它们呢?
据我所知,我只能返回一件事,这取决于函数名前面的类型。
如果我有一个产生结果int
和结果的函数string
,如何从一个函数中返回它们呢?
据我所知,我只能返回一件事,这取决于函数名前面的类型。
Answers:
我不知道您string
是什么人,但我将假设它管理自己的内存。
您有两种解决方案:
1:返回struct
包含所有所需类型的。
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
长度,除非对于函数分配自己的字符串和/或return绝对至关重要NULL
。
getPair
然后该函数取消引用。根据您正在执行的操作(OP从未明确这是否实际上是一个C问题),分配可能是个问题,但通常不在C ++领域(返回值优化保存所有这些)和C领域中的数据复制通常显式地发生(通过strncpy
或其他方式)。
Option 1
:声明一个带有int和string的结构,并返回一个struct变量。
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
的方式。
两种不同的方法:
我认为#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__)
这样就可以从一个函数最多返回四个变量,并将它们分配给最多四个变量。例如,您可以像这样使用它们:
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语句变量声明需要C99或更高版本。但是我认为在这里发布足够有趣。另一个问题是,如果为它们分配错误的值,则编译器不会警告您,因此您必须小心。
其他示例以及使用联合的基于堆栈的代码版本在我的github存储库中可用。
__typeof__
string
你的意思是“我使用C ++,这是std::string
类”或“我用C,这是一个char *
指针或char[]
数组。”