如何从C函数中生成数组返回类型?
我试图返回数组名称,如下所示。 基本上我试图让函数测试返回一个可以在main中使用的数组。 你能告诉我需要阅读的内容,以了解如何执行这样的function吗?
#include 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
函数无法在C中返回数组。
但是,他们可以返回结构。 结构可以包含数组……
您可以通过返回指针返回一个数组(数组衰减到指针)。 但是,在您的情况下这将是不好的,因为那时您将返回指向局部变量的指针,这会导致未定义的行为。 这是因为返回的指针指向的内存在函数返回后不再有效,因为堆栈空间现在被其他函数重用。
你应该做的是将数组及其大小作为参数传递给函数。
您的代码中还有另一个问题,那就是使用大小为2的数组,但写入第三个元素。
您需要在堆上分配内存并返回指针。 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; }
错误消息的第一行意味着它所说的内容:您已将该函数声明为返回int
,但您尝试返回指针。
更大的问题(如错误消息的第二行告诉您)是您尝试返回指针的数组是本地数组,因此当函数返回并且不再有效时将超出范围。
你应该做的是使用malloc
或new
动态分配一个数组(即一块连续的内存)并返回一个指向它的指针。 当然,确保在完成记忆后释放内存。
不幸的是,C不支持返回任意数组,也不支持函数的匿名结构,但有两种解决方法。
第一种解决方法是创建一个包含数组的结构。 它将具有与数组相同的大小,在堆栈上分配以确保空间局部性。
例如
typedef struct { int arr[5]; } my_array1; typedef struct { int values[3]; } factorFunctionReturnType_t;
第二种解决方法是发明一个静态内存池(例如,仅为此数组提供自定义malloc / free的数组),这将有效地允许您从此池动态分配内存,同样有效地返回指向连续堆栈空间的指针,根据定义是一个数组。
例如
#include static uint8_t static_pool[2048];
然后实现管理此特定内存池的my_alloc,my_free,再次确保创建的内存在堆栈上,并且内存已经由应用程序apriori拥有(而malloc可能会分配先前无法通过应用程序访问的内存或者如果内存不足则崩溃并没有检查失败的回报)。
第三种解决方法是让函数将局部变量返回给回调函数; 这确保了一旦函数完成,您可以使用结果而不会破坏堆栈,因为使用内存的函数将位于包含堆栈的作用域之上。
#include #include 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; }
这比非堆栈式内存池更有效,它需要做出决策以避免碎片,比堆栈式内存池更有效,它只是将结果放在堆栈顶部,因为它不需要复制字符串,等等线程安全因为函数的返回值不会被另一个线程覆盖(除非使用锁定)。
有趣的是,所有“函数式编程范式”程序最终强调通过链接回调函数,有效地在堆栈上分配,可以在没有任何malloc的情况下编写C程序。
这有一个有趣的副作用,使链接列表不再缓存恶意(因为堆栈上分配的回调链接列表将在堆栈上彼此接近,这使您可以执行诸如运行时字符串操作而没有任何mallocs,并让你建立了未知大小的用户输入而没有做任何mallocs。
C不主张将局部变量的地址返回到函数外部,因此您必须将局部变量定义为静态变量。
#include /* 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; }
我的建议是传入一个数组来填写:
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]
超出了数组。
#include #include 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; }
您还可能希望确保您设置的索引实际存在于您的数组中,如上所述
这是传回数组的另一种方法:
int test(){ static int factorFunction[3]; factorFunction[0] = 5 + x; factorFunction[1] = 7 + x; factorFunction[2] = 9 + x; return factorFunction; }
静态表示变量将以保留在内存中的方式进行分配。 因此,如果您有一个固定的值,并希望它在函数调用之间保留在内存中,这是一种方法。
首先,您无法直接从C函数返回数组。 你可以做的是你可以在该函数中返回数组的地址。 在这种情况下,该函数将如下所示:
int* test(int size, int x){ /* function body */ return factorFunction; }
要接收数组,您需要一个指针 – 而不是数组。
所以,而不是使用int factors[2];
你必须使用int *factors;
在你的main
function。
其次,即使你返回数组的地址,这段代码也行不通; 因为你试图返回本地数组的地址; 在执行该函数后将不存在。 解决此问题的一种简单方法是将本地数组(在本例中为factorFunction
)声明为static。
考虑到这两个问题,functiontest
将如下所示:
int* test(int size, int x){ static int factorFunction[size]; /* function body */ return factorFunction; }
首先,除非您的C99具有VLA ,否则数组大小应该在C中保持不变。您不能使用以下语句:
int factorFunction[size];
其次,您尝试返回在函数中创建的数组,该数组将从范围中删除。
要避免这种情况,可以在测试函数中将数组作为参数,或者使用malloc
函数动态创建数组。 顺便说一句,你的test
函数可以返回指向更新数组的指针。
一个非常非常基本的代码和非常非常基本的解释如何将数组从用户定义的函数返回到main函数。希望它有帮助!! 下面我给出了完整的代码,让任何人都能理解它是如何工作的? 🙂 🙂
#include using namespace std; int * function_Random()// function with returning pointer type of integer { static int arr[100]; cout<<"We are Inside FunctionRandom"<