[英]returning multiple values from function c
我来自c#,这给我带来了比我预期更多的问题。 我还没有看到直接的解决方案。 我是C语言的新手,只是玩弄它,而我尝试过的所有各种实现(从使用结构到传递指针)都无法完成工作。 (本地值不变)。 有人可以给我一个干练的例子吗?
这是我的代码示例
#include <stdio.h>
//alter values based on input
int * doStuff(int a, int b){
int input;
int arr[2]
scanf("%d", &option);
switch(option);
case 1:
arr[0] = a-2;
arr[1] = b;
return arr;
break;
case 2:
arr[0] = a;
arr[1] = b-2;
return arr;
break;
default:
return a, b;
}
main(){
int a = 20;
int b = 20;
int returnedObject[2];
//what i need is like in c# how I can do this
returnedObject = doStuff(a, b);
a = returnedObject[0];
b= returnedObject[1];
}
我需要传递值,更改它们,返回它们并设置局部变量。 我完全迷失了一些更复杂的例子。 来自c#指针,数组,它们的工作方式让我迷失了,而且它没有我期望的那么简单。
C语言中的函数不能返回数组类型,数组也不能成为赋值的目标。 所以代码像
int returnedObject[2];
returnedObject = doStuff( a, b );
无法工作。 C函数可以返回指向数组的指针 ,但是我不认为您想要了解它。
C函数不能返回多个对象,也不支持多个分配。
如果两个值在逻辑上是某个较大的聚合类型的属性,则可以使用struct
类型返回具有多个属性的单个对象,例如
struct result { int x, int y };
struct result doStuff( int a, int b )
{
struct result ret = {a, b}; // initialize struct with inputs
...
case 1:
ret.x = a-2;
break; // y remains unchanged
case 2:
ret.y = b-2;
break; // x remains unchanged
...
return ret;
}
你称之为
struct result stuff;
stuff = doStuff( a, b );
或者,您可以将指针传递给您的值,并根据需要更新它们:
void doStuff( int *a, int *b )
{
...
case 1:
*a = *a - 2;
break;
case 2:
*b = *b - 2;
break;
}
你称之为
doStuff( &a, &b );
在这种情况下,您实际上不会向调用者返回任何内容。
您可以将数组作为参数传递给函数,如下所示:
void doStuff( int a, int b, int *result )
{
result[0] = a;
result[1] = b;
...
case 1:
result[0] = a - 2;
break;
case 2:
result[1] = b - 2;
break;
...
}
你称之为
int results[2];
int a;
int b;
...
doStuff( a, b, results );
请注意,当我们将数组表达式传递给函数时,其类型从int [2]
更改为int *
。 除非它是sizeof
或一元&
运算符的操作数,或者是用于初始化另一个数组的字符串文字,否则类型“ N的T
元素数组”的表达式将被转换(“衰变”)为类型的表达式“指向T
指针”,表达式的值将是数组第一个元素的地址。 C中的数组表达失去在大多数情况下,1他们的“阵性”。 您可以像使用数组表达式一样在指针表达式上使用下标运算符[]
(数组索引操作a[i]
定义为*(a + i)
),但是指针不是数组,反之亦然。
将返回类型设置为int *
。
创建一个局部变量int *result = malloc(sizeof(int) * 2);
然后将您的a
和b
或任何您需要返回的result
放入。
调用函数时,将结果分配给int *
。
int *res;
res = doStuff(a, b);
a = res[0];
b = res[1];
malloc
为堆上的result
分配空间。 它的输入是您需要的字节数。
2个int
,每个int
4个字节-> 8个字节== 2*sizeof(int)
问题在于,每次调用函数时,您将继续分配越来越多的空间。 C不会为您执行垃圾回收,因此当您使用int *res
完成操作时,应通过调用free(res)
释放该空间。
更多详情:
在C#中,您将像这样初始化一个数组: int[] result = new result[2];
您是否都尝试过打印类似Console.WriteLine(myarray);
的数组Console.WriteLine(myarray);
。 它行不通吗? C#我相信可以打印类似System.Int32[]
东西。 如果您使用Java( System.out.println(myarray);
)完成此操作,它将打印一些奇怪的数字。
该数字实际上是数组的地址。
当引用数组myarray
,实际上是在引用数组的地址。 当您执行诸如myarray[1]
,您将获取myarray
的地址,并向其添加1*sizeof(int)
并获取该值。
在C语言中,您可以按照典型的方式定义数组: int arr[2];
分配2个整数的空间。
或者,您可以执行以下操作: int *arr;
它定义了一个指针(或地址)。 但是,您需要告诉它为整数分配空间。 到目前为止, arr
并没有真正指向任何东西。 您可以通过调用malloc
分配空间: arr = malloc(2*sizeof(int));
动态分配2个整数的空间。
现在,您可以将内容放入数组中。 arr[0] = 1
。
[]
有效地执行了指针算术。
arr[1] is the same as *(arr + 1)
arr + 1
正在获取数组的地址并将其加1。 C看到您要添加一个int *
因此它将1解释为1个int(4个字节)。 *
运算符取消引用该地址,这意味着它跟随指针并获取存储在该地址的值。
如果打印arr
给您0x1000
, arr+1
给您0x1004
, *
将返回存储在0x1004
的int。
返回函数中的返回数组。
在C语言中,您无法像在C#中那样返回一个数组( int[] function(...)
),但是您可以返回一个指针( int *function(...)
),该指针可以像一个数组(参见上面的示例)。
您要使用malloc
的原因是因为malloc
在堆上分配了空间,因此您可以在函数返回后使用该数组。 如果您定义了类似int arr[2];
的数组int arr[2];
,该空间将在堆栈上分配,并且该函数返回后该数组将不会保留。
也许您应该看一下教程以了解有关指针的更多信息。 我认为我的回答太冗长,与问题不完全相关。
简单的解决方案(通过引用/指针传递允许更改存储的值)
#include <stdio.h>
//alter values based on input
void doStuff(int *a, int *b, int option)
{
switch(option)
{
case 1:
// a decremented by 2, b is unchanged
*a = *a - 2;
break;
case 2:
// b decremented by 2, a is unchanged
*b = *b - 2;
break;
default:
// a and b are unchanged
break;
}
}
int main()
{
int a = 20;
int b = 20;
int option;
printf("Enter option (1 or 2):\n");
scanf("%d", &option);
printf("BEFORE doStuff() :: a = %d, b = %d\n", a, b);
doStuff(&a, &b, option);
printf("AFTER doStuff() :: a = %d, b = %d\n", a, b);
return 0;
}
您可以使用结构将数组包装起来以直接返回它。
#include <stdio.h>
struct doStuffRet {
int arr[2];
};
//alter values based on input
struct doStuffRet doStuff(int a, int b){
int option;
struct doStuffRet r = {{a, b}};
scanf("%d", &option);
switch(option) {
case 1:
r.arr[0] = a-2;
r.arr[1] = b;
return r;
break;
case 2:
r.arr[0] = a;
r.arr[1] = b-2;
return r;
break;
default:
return r;
}
}
int main(void){
int a = 20;
int b = 20;
struct doStuffRet returnedObject;
//what i need is like in c# how I can do this
returnedObject = doStuff(a, b);
a = returnedObject.arr[0];
b = returnedObject.arr[1];
printf("%d %d\n", a, b);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.