如何在 C 中 return 2 个一维数组从函数到主函数

How to return 2 1D arrays from function to main in C

#include <stdio.h>
int *func()
{
   int *a=malloc(5);
   int *b=malloc(5);
   for(int i=0;i<5;i++)
   {
     a[i]=i+1;
     b[i]=i+5;
   }
   int *l= malloc(2);
   l[0]=a;
   l[1]=b;
   //printf("%p %p ",l[0],l[1]);
   return l;
} 
int main() 
{ 
  int *k=func();
} 

对于上面的代码,如何returna,b数组到main函数? 在为两个数组 a 和 b 赋值后,我将它们的地址赋给了新数组 l。现在 return 将 l 转到 main 后,如何在 main 函数中绘制数组 a 和 b 的值?

您可以通过以下方式进行

struct Array
{
    int a[5];
    int b[5];
};

struct Array func( void )
{
    struct Array a = 
    { 
        {1,2,3,4,5},
        {1,2,3,4,5}
    };

    return a;
}

int main( void )
{
   struct Array a = func();
   //...
} 

另一种方法是动态分配数组,return 指针通过输出参数从函数分配数组。例如

#include <stdio.h>
#include <stdlib.h>

void func( int **a, size_t *n1, int **b, size_t *n2 )
{
    *n1 = 5;
    *a = malloc( sizeof( int ) * *n1 );
    
    if ( *a != NULL )
    {
        int value = 1;
        for ( size_t i = 0; i < *n1; i++ )
        {
            ( *a )[i] = value++;
        }
    }
    
    *n2 = 5;
    *b = malloc( sizeof( int ) * *n2 );
    
    if ( *b != NULL )
    {
        int value = 1;
        for ( size_t i = 0; i < *n2; i++ )
        {
            ( *b )[i] = value++;
        }
    }
}

int main(void) 
{
    int *a = NULL;
    int *b = NULL;
    size_t n1 = 0;
    size_t n2 = 0;
    
    func( &a, &n1, &b, &n2 );
    
    //...

    free( a );
    free( b );
    
    return 0;
}
void func(int **aa, int **bb)
{
    static int a[5]={1,2,3,4,5};
    static int b[5]={1,2,3,4,5};

    *aa = a;
    *bb = b;
}

void func2(int **aa, int **bb)
{
    int *a = malloc(5 * sizeof(*a)); 
    int *b = malloc(5 * sizeof(*b)); 
    
    memcpy(a, (int []){1,2,3,4,5}, 5 *sizeof(*a));
    memcpy(b, (int []){1,2,3,4,5}, 5 *sizeof(*b));

    *aa = a;
    *bb = b;
}


typedef struct
{
    int a[5];
    int b[5];

}mydata;

mydata func1(void)
{
    mydata d = { .a = {1,2,3,4,5}, .b = {1,2,3,4,5}};
    
    /*  ... */
    return d;
}

第二种方法非常昂贵,因为正在通过(在大多数实现中)堆栈复制整个结构。

用法示例:

int main(void)
{
    int *a,*b;

    func2(&a, &b);

    for(size_t i = 0; i < 5; i++)
    {
        printf("a[%zu] = %d, b[%zu]=%d\n", i, a[i], i, b[i]);
    }
}

C 中的函数只能 return 一个单一的事物 - 那个事物可以是具有多个属性的 struct,但你不能 return 并像在 Python 或 Perl 中那样分配多个独立项。

如果调用者需要函数中的几个独立项目,那么您将需要使用多个输出参数 - 调用者必须传递指向它希望函数更新的事物的指针,而函数更新所指向的事物:

bool f( T *a, T *b )          // for some arbitrary type T
{
  /**
   * The *expressions* *a and *b have type T; writing to *a 
   * and *b in f is equivalent to writing to x and y in main.  
   */
  *a = new_T_value();         // writes a new value to the thing a points to
  *b = another_new_T_value(); // writes a new value to the thing b points to
  return some_boolean_value();
}

int main( void )
{
  T x, y;             // for some arbitrary type T
  if ( f( &x, &y ) )  // f will write new values to x and y
    do_something();
  ...
}

我们可以用指针类型 P * 替换 T,这给我们:

bool f( P **a, P **b )            // for some arbitrary type P
{
  /**
   * The expressions *a and *b have type P *; writing to *a and *b
   * in f is equivalent to writing to x and y in main.
   */
  *a = new_Pstar_value();         // writes a new value to the thing a points to
  *b = another_new_Pstar_value(); // writes a new value to the thing b points to
  return some_boolean_value();
}

int main( void )
{
  P *x, *y;             // for some arbitrary type T
  if ( f( &x, &y ) )    // f will write new values to x and y
    do_something();
  ...
}

语义完全相同 - 我们希望函数 f 将新值写入 xy,因此我们必须将指针传递给 xy 作为参数。只是在这种情况下 xy 已经有一个指针类型 (P *),所以我们最终将指针传递给指针 (P **).

这是最直接的方法,需要对现有代码进行最少的更改:

#include <stdio.h>
#include <stdlib.h> // need this for malloc

/**
 * We want func to dynamically allocate arrays of int and
 * assign the resulting pointers to *a and *b.  We also want
 * to dynamically allocate and return an array of int *.
 */
int **func( int **a, int **b)
{
   /**
    * malloc(5) allocates 5 *bytes*, not 5 ints.
    * We need to multiply the number of things we 
    * want by the size of each thing.  
    */
   *a=malloc(5 * sizeof **a); // sizeof **a == sizeof (int)
   *b=malloc(5 * sizeof **b);

   for(int i=0;i<5;i++)
   {
     /**
      * The postfix [] operator has higher precedence than the
      * unary * operator; we don't want to dereference a[i] and 
      * b[i], we want to index into what a and b *point to*, so
      * we must explicitly group the * operator with the variable
      * name. 
      */
     (*a)[i]=i+1; 
     (*b)[i]=i+5;  
   }
   /**
    * Each l[i] holds a value of type int *,
    * so l needs to have type int **
    */
   int **l= malloc(2 * sizeof *l);
   l[0]=*a;
   l[1]=*b;
   //printf("%p %p ",l[0],l[1]);
   return l;
} 

int main( void ) 
{ 
  int *a, *b;
  int **k=func( &a, &b );
}