从函数c

时间:2015-10-25 03:30:22

标签: 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#指针,数组,它们如何工作正在失去我,它并不像我预期的那么简单。

4 个答案:

答案 0 :(得分:2)

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)),但指针不是数组,反之亦然。

<小时/> 1。请注意,我说的是表达式,而不是对象。数组对象始终保持数组对象

答案 1 :(得分:1)

返回类型int *

创建一个本地变量int *result = malloc(sizeof(int) * 2);并将ab或您需要返回的任何内容放在result中。

调用该函数时,将结果分配给int *

int *res;
res = doStuff(a, b);
a = res[0];
b = res[1];

malloc在堆上为result分配空间。它的输入是你需要的字节数。

2 int s,每个int 4个字节 - &gt; 8个字节== 2*sizeof(int)

问题在于,每次调用函数时,都会继续分配越来越多的空间。 C不会为您进行垃圾回收,所以当您使用int *res完成后,您应该通过调用free(res)free该空间。

更多详情:

在C#中,您将初始化一个这样的数组:int[] result = new result[2];

你们每个人都试过像这样打印一个数组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并没有真正指向任何事物。您可以通过调用mallocarr = 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处存储的整数。

在函数中返回数组。

在C中,你不能像C#(int[] function(...))那样返回一个数组,但你可以返回一个指针(int *function(...)),你可以像数组一样使用它(见上文)例子)。

您要使用malloc的原因是因为malloc在堆上分配空间,因此您可以在函数返回后使用该数组。如果您定义了一个类似int arr[2];的数组,则会在堆栈上分配空间,并且在函数返回后数组不会持久存在。

也许您应该查看教程以了解有关指针的更多信息。我认为我的答案过于冗长,与问题并不完全相关。

答案 2 :(得分:1)

简单的解决方案(通过引用/指针传递允许更改存储的值)

#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;
}

答案 3 :(得分:1)

您可以使用结构包装数组以直接返回它。

#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;
}