【发布时间】:2011-08-10 01:58:29
【问题描述】:
现在,如果我尝试访问这个数组,比如int a = fibonacci(10);,它会毫无怨言。但是,如果我尝试访问单个元素,例如 a[1],它会告诉我
下标值既不是数组也不是指针
我做错了什么?
【问题讨论】:
-
打开编译器警告并检查所有消息。
标签: c arrays function pointers return
现在,如果我尝试访问这个数组,比如int a = fibonacci(10);,它会毫无怨言。但是,如果我尝试访问单个元素,例如 a[1],它会告诉我
下标值既不是数组也不是指针
我做错了什么?
【问题讨论】:
标签: c arrays function pointers return
.. 如果我尝试访问一个单独的元素,例如 a[1] 或其他东西 ..
int a = fibonacci(10);
a 是一个整数变量,而不是数组,可以在其上使用运算符 []。
方法定义应该是-
int* fibonacci(int ceiling)
{
// ...
return arr ;
}
int *a = fibonacci(10) ;
现在您可以在a 上使用[] 运算符。 然而,你返回的是一个局部变量的引用(即,驻留在堆栈上),这是错误的。您应该使用malloc 为数组动态分配内存,稍后再使用free 它。
【讨论】:
[],提及您希望访问的变量的索引。
你应该返回一个 int[],而不是一个 long
编辑: 抱歉,混合 C# :)
int* fibonacci(int ceiling)
....
// 调用
int *a = fibonacci (10);
int val = a[20];
【讨论】:
它应该返回一个 long*,而 arr 应该是 long*,它从堆中获取内存,因为 a) 你希望你的数组在函数返回后仍然存在 b) 你的所有操作数都是 long 类型:
long* fibonacci(int ceiling)
{
int counter;
long num1 = 0, num2 = 1, sum; //F is seeded with F(0) = 0, F(1) = 1
long* arr = malloc((ceiling+1)*sizeof(long));
//include ceiling in the loop since you have ceiling+1 elements
for (counter = 0; counter <= ceiling; counter++)
{
arr[counter] = num1;
//printf("%d\n", num1); //prints sequence
sum = num1+num2;
num1 = num2;
num2 = sum;
}
return arr;
}
【讨论】:
解决此问题的最简单方法是在调用站点分配数组并将其传递给要填充的斐波那契函数。
void fibonacci(int n, int arr[])
【讨论】:
比上面所说的更重要的是,您应该考虑内存分配。
仅使用int arr[ceiling+1]; 将为具有此函数范围的变量创建内存。因此,您可能会返回一个指向内存位置中的数组的指针,该指针可能会被覆盖。
改用 malloc
【讨论】:
修复了错误的更好版本:
#include <stdio.h>
int fibonacci(int ceiling, int *arr)
{
int counter;
long num1 = 1, num2 = 1, sum;
if(arr == NULL)
return -1;
for (counter = 0; counter < ceiling; counter++) {
arr[counter] = num1;
//printf("%d\n", num1); //prints sequence
sum = num1+num2;
num1 = num2;
num2 = sum;
}
return 0;
}
int main (int argc, char const* argv[])
{
int ceiling = 10;
int arr[ceiling + 1];
fibonacci(ceiling, arr);
return 0;
}
【讨论】:
您不能从 C(或 C++)中的函数返回数组。
您的代码当前所做的是:它将 int[] 数组隐式衰减为 int* 指针,然后将 int* 隐式转换为 long,然后返回 long。这不是指针或数组,因此可能无法对其应用下标运算符。
你可以返回一个 int*,但返回一个指向本地 arr 数组的指针是错误的(你的编译器可能无法捕捉到错误,但你会调用 undefined behavior 在runtime) 因为一旦函数完成,arr正式不存在,因此返回的指针是悬空的。
你可以:
用 malloc() 分配一个数组并返回指针(但你必须弄清楚谁将释放()分配,并确保只发生一次);或
传入一个指向数组的指针,并通过该指针填充数组(现在调用者负责创建和管理数组)——这可能是 C 中的常用方法;或
创建一个包装数组的结构,并返回其中一个(或者,就此而言,传递一个指向其中一个的指针)。
还要注意int arr[ceiling + 1]; 是一个C99 结构;它在标准“传统”C(C89 等)中是不允许的,在符合标准的 C++ 中也不允许。在那些语言中,数组的大小必须在编译时知道。
在 C++ 中,您还可以通过引用传递数组,或使用 boost::array(这是“包装数组的结构”,但也使用运算符重载使其行为更透明,就像数组一样)。
【讨论】: