如何从C函数中生成数组返回类型?

时间:2013-01-12 19:36:34

标签: c

我试图返回数组名称,如下所示。基本上我试图让函数测试返回一个可以在main中使用的数组。你能告诉我我需要阅读更多内容以了解如何执行这样的功能吗?

#include <stdio.h>

int test(int size, int x){
    int factorFunction[size];    
    factorFunction[0] = 5 + x;
    factorFunction[1] = 7 + x;
    factorFunction[2] = 9 + x;
    return factorFunction;
}

int main(void){
    int factors[2];
    factors = test(2, 3);
    printf("%d", factors[1]);
    return 0;
}

我收到编译错误:

smallestMultiple.c:8: warning: return makes integer from pointer without a cast
smallestMultiple.c:8: warning: function returns address of local variable
smallestMultiple.c: In function ‘main’:
smallestMultiple.c:13: error: incompatible types in assignment

14 个答案:

答案 0 :(得分:13)

函数无法在C中返回数组。

然而,他们可以返回结构。结构可以包含数组......

答案 1 :(得分:13)

您可以通过返回指针返回数组(数组衰减到指针)。但是,在您的情况下这将是不好的,因为那时您将返回指向局部变量的指针,这会导致未定义的行为。这是因为返回的指针指向的内存在函数返回后不再有效,因为堆栈空间现在被其他函数重用。

你应该做的是将数组及其大小作为函数的参数传递。

您的代码中还有另一个问题,那就是使用大小为2的数组,但写入第三个​​元素。

答案 2 :(得分:9)

您需要在堆上分配内存并返回指针。 C不能从函数返回数组。

int* test(int size, int x)
{
    int* factorFunction = malloc(sizeof(int) * size);    
    factorFunction[0] = 5 + x;
    factorFunction[1] = 7 + x;
    factorFunction[2] = 9 + x;
    return factorFunction;
}

答案 3 :(得分:3)

错误消息的第一行意味着它所说的内容:您已将该函数声明为返回int,但您尝试返回指针。
更大的问题(正如错误消息的第二行告诉你的那样)是你试图返回指针的数组是一个本地数组,因此当函数返回时不再是有效。
你应该做的是使用mallocnew动态分配一个数组(即一块连续内存)并返回一个指向它的指针。当然,确保在完成记忆后释放记忆。

答案 4 :(得分:2)

不幸的是,C不支持从函数返回任意数组或匿名结构,但有两种解决方法。

第一个解决方法是创建一个包含数组的结构。它将具有与数组相同的大小,在堆栈上分配,确保空间局部性。

e.g。

typedef struct {
    int arr[5];
} my_array1;

typedef struct {
    int values[3];
} factorFunctionReturnType_t;

第二种解决方法是发明一个静态内存池(例如,仅为此数组提供自定义malloc / free的数组),这将有效地允许您从此池动态分配内存,同样有效地返回指向连续堆栈的指针space,根据定义是一个数组。

e.g。

#include <stdint.h>
static uint8_t static_pool[2048];

然后实现管理此特定内存池的my_alloc,my_free,再次确保创建的内存在堆栈上,并且内存已经由您的应用程序apriori拥有(而malloc可能会分配以前无法通过应用程序访问的内存或崩溃,如果没有足够的内存,也没有检查失败的回报。)

第三种解决方法是让函数将局部变量返回给回调函数;这确保一旦函数完成,您可以使用结果而不会破坏堆栈,因为使用内存的函数将位于包含堆栈的范围之上。

#include <stdint.h>
#include <stdio.h>

void returnsAnArray(void (*accept)(void *)) {
    char result[] = "Hello, World!";    

    accept(result);
}

void on_accept(void *result) {
    puts((char *)result);
}

int main(int argc, char **argv)
{
    returnsAnArray(on_accept);

    return 0;
}

这比非堆栈式内存池更有效,它需要做出决策以避免碎片,比堆栈式内存池更有效,因为它不需要复制将结果放在堆栈顶部字符串,更多线程安全,因为函数的返回值不会被另一个线程覆盖(除非使用锁)。

有趣的是,所有&#34;功能编程范例&#34;程序最后强调你可以通过链接回调函数来编写没有任何malloc的C程序,有效地在堆栈上进行分配。

这有一个有趣的副作用,使链表不再缓存恶意(因为堆栈上分配的回调链接列表都将在堆栈上彼此靠近,这使您可以执行诸如运行时字符串操作之类的操作,而无需任何mallocs ,并允许您构建未知大小的用户输入而无需执行任何malloc。

答案 5 :(得分:1)

C不主张将局部变量的地址返回到函数外部,因此您必须将局部变量定义为静态变量。

#include <stdio.h>

/* function to generate and return random numbers */
int * getRandom( ) {

   static int  r[10];
   int i;

   /* set the seed */
   srand( (unsigned)time( NULL ) );

   for ( i = 0; i < 10; ++i) {
      r[i] = rand();
      printf( "r[%d] = %d\n", i, r[i]);
   }

   return r;
}

/* main function to call above defined function */
int main () {

   /* a pointer to an int */
   int *p;
   int i;

   p = getRandom();

   for ( i = 0; i < 10; i++ ) {
      printf( "*(p + %d) : %d\n", i, *(p + i));
   }

   return 0;
}

答案 6 :(得分:0)

#include <stdio.h>

#include <stdlib.h>

int* test(int size, int x){
    int *factorFunction = (int *) malloc(sizeof(int) * size);    
    if( factorFunction != NULL ) //makes sure malloc was successful
    {
        factorFunction[0] = 5 + x;
        factorFunction[1] = 7 + x;
        factorFunction[2] = 9 + x; //this line won't work because your array is only 2 ints long

    }
return factorFunction;
}

int main(void){
    int *factors;
    factors = test(2, 3);
    printf("%d", factors[1]);
    //just remember to free the variable back to the heap when you're done
    free(factors);
    return 0;
}

您还可能希望确保您设置的索引实际存在于您的阵列中,如上所述

答案 7 :(得分:0)

首先,除非您的C99具有VLA s,否则数组大小应该在C中保持不变。您不能使用以下语句:

int factorFunction[size];

其次,您正在尝试返回在函数中创建的数组,该数组将从范围中删除。

为避免这种情况,您可以将数组作为测试函数中的参数,或使用malloc函数动态创建数组。顺便说一句,你的test函数可以返回指向更新数组的指针。

答案 8 :(得分:0)

我的建议是传入一个数组来填写:

void test(int size, int factors[], int x){
    factorFunction[0] = 5 + x;
    factorFunction[1] = 7 + x;
    factorFunction[2] = 9 + x;
}

int main(void){
    int factors[3];
    test(3, factors, 3);
    printf("%d", factors[1]);
    return 0;
}

使用此方法,您不必担心分配,并且以后不需要释放数组。

我还修复了数组的大小,所以你不要用第三个元素写出它。请记住,C数组声明为“您想要多少”,然后从0 ... (how_many-1)编入索引,因此使用[2]声明的数组上的[2]超出了数组。

答案 9 :(得分:0)

以下是传回数组的另一种方法:

    int test(){
        static int factorFunction[3];    
        factorFunction[0] = 5 + x;
        factorFunction[1] = 7 + x;
        factorFunction[2] = 9 + x;
        return factorFunction;
    }

静态表示将以保留在内存中的方式分配变量。因此,如果您有一个固定的值,并希望它在函数调用之间保留在内存中,这是一种方法。

答案 10 :(得分:0)

首先,您无法直接从C函数返回数组。你可以做的是你可以在该函数中返回数组的地址。在这种情况下,该函数将如下所示:

int* test(int size, int x){

    /* function body */

    return factorFunction;
}

要接收数组,你需要一个指针 - 而不是一个数组。

因此,您必须在int factors[2];函数中使用int *factors;,而不是使用main

其次,即使你返回数组的地址,这段代码也行不通;因为你试图返回本地数组的地址;在执行该函数后将不存在。解决此问题的一种简单方法是将本地数组(在本例中为factorFunction)声明为静态。

考虑到这两个问题,函数test将如下所示:

int* test(int size, int x){

    static int factorFunction[size];

    /* function body */

    return factorFunction;
}

答案 11 :(得分:0)

要记住两点:

  1. 如果要从函数返回一维数组,则必须声明一个返回指针的函数。

  2. C不主张将局部变量的地址返回到函数外部,因此您必须将局部变量定义为静态变量。

请参阅此链接: https://www.tutorialspoint.com/cprogramming/c_return_arrays_from_function.htm

答案 12 :(得分:0)

  // example for to create a array in function and it return using pointer
  //if you want use malloc use header #include <stdlib.h>
      int * printsquares(int a[],int size){  //to declare aa function

      int* e = malloc(sizeof(int) * size);  //to create array using malloc
       for(int i=0;i<size;i++){    
             e[i]=i*i;       //assign the square root values
      }



   return e;


 }

答案 13 :(得分:-1)

  

非常非常基本的代码和非常基本的解释如何返回   数组从用户定义的函数返回到main函数。希望它   帮助!下面我给出了完整的代码,让任何人都能理解   它是如何工作的? :):)

#include<iostream>
using namespace std;

int * function_Random()// function with returning pointer type of integer
{
     static int arr[100];
     cout<<"We are Inside FunctionRandom"<<endl;
    for(int i=0;i<100;i++)//loop to add elements in array
    {
        arr[i]=rand();//rand() function to put random numbers generated by system
        cout<<"\t"<<arr[i]; //to show how our array will look
    }
    cout<<endl<<endl;//endl for end line to look well formatted 
    return arr;
}
int main()
{


    int *arrptr; //pointer to get back base address of array
    arrptr=function_Random();//function that returns base address
    cout<<"We are Inside Main"<<endl;
    for(int j=0;j<100;j++)
    {
         cout<<"\t"<<arrptr[j];//returned base address has complete link of array that's why it is able to print the array:contiguous memory locations.
    }       
    return 0;//nothing to return that's why 0
}