我试图返回数组名称,如下所示。基本上我试图让函数测试返回一个可以在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
答案 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
,但您尝试返回指针。
更大的问题(正如错误消息的第二行告诉你的那样)是你试图返回指针的数组是一个本地数组,因此当函数返回时不再是有效。
你应该做的是使用malloc
或new
动态分配一个数组(即一块连续内存)并返回一个指向它的指针。当然,确保在完成记忆后释放记忆。
答案 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)
要记住两点:
如果要从函数返回一维数组,则必须声明一个返回指针的函数。
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
}