【问题标题】:Declaring Array in C with variable length [closed]在C中声明具有可变长度的数组[关闭]
【发布时间】:2021-10-26 01:41:02
【问题描述】:

这段代码给了我斐波那契数

#include <stdio.h>

int main()
{
    int n; //integer overflow error for n > 47

    printf("How many Fibonacci numbers?\n");
    scanf("%d", &n);

    int fibs[n];

    fibs[0] = 0;
    fibs[1] = 1;

    printf("%d ", fibs[0]);
    printf("%d ", fibs[1]);

    for(int i = 2; i < n; i++)
    {
        fibs[i] = fibs[i - 2] + fibs[i - 1];
        printf("%d ", fibs[i]);
    }
    return 0;
    //gives 0 1 1 2 3 5 8 13 21 34 for n = 10

}

但这给了我错误的输出,但没有错误

#include <stdio.h>

int main()
{
    int n, fibs[n];//change

    printf("How many Fibonacci numbers?\n");
    scanf("%d", &n);

    fibs[0] = 0;
    fibs[1] = 1;

    printf("%d ", fibs[0]);
    printf("%d ", fibs[1]);

    for(int i = 2; i < n; i++)
    {
        fibs[i] = fibs[i - 2] + fibs[i - 1];
        printf("%d ", fibs[i]);
    }
    return 0;
    //gives 0 1 for n = 10
}

我知道它肯定与数组有关,而且它的大小没有被定义,但我无法理解到底是什么问题。

有人能解释一下这里发生了什么吗?

【问题讨论】:

  • 请给出准确的输入、预期结果和实际结果。另外,您能否指出两个代码示例之间的区别(除了额外的注释)?
  • 两者的代码一样吗? (虽然你真的需要在使用n之前检查scanf()是否成功。
  • 除了注释不同之外,您的两个程序完全相同。为了改进问题,您应该只包含不工作的版本,并显示您提供给程序的确切输入,这会导致意外行为;并描述行为与您的预期有何不同
  • 你真的不需要保留所有斐波那契数的数组。在任何时候你都没有真正使用超过 3 个整数。
  • int n, fibs[n]; 在您尝试创建一个大小为未初始化变量的数组时会导致未定义的行为。你真的期望会发生什么?

标签: arrays c fibonacci


【解决方案1】:

我在您的代码中看到的一件大事是 int n, fibs[n]; 行。变量 n 位于堆栈上,因为它是一个局部变量。这意味着它的值在初始化之前实际上可以是任何东西。并且由于您使用该值声明数组,因此该数组具有随机的未知长度。如果有效,那纯属巧合。这就是为什么您的第一个代码版本可以工作的原因,因为数组被声明为 AFTER 初始化 n 的 scanf。我认为创建具有可变数量数组元素的数组的更好方法是改用 malloc...

int n, *fibs;
printf("How many Fibinocci numbers?\n");
scanf("%d", &n);
fibs = malloc(sizeof(int) * n);
if (fibs == NULL)
{
    fprintf(stderr, "Unable to allocate sufficient memory for operation.\n");
    exit(1);
}

然后您可以使用数组索引 fibs[0]、fibs[1] 等...来访问内存块中的不同位置。

为什么会这样?因为int fibs[n]LIKE 一个指向内存块的指针。从技术上讲,它们并不相同,但您通常可以将指向内存块的指针用作数组。这仅适用于一维数组,因为编译器不知道有多少列。但要解决这个问题,您可以像这样手动计算(i 是行,j 是列):

数组[i * 列 + j];

【讨论】:

    【解决方案2】:

    int n, fibs[n]; 尝试使用n 作为长度来定义一个数组,但是n 还没有被初始化,所以它的值是不确定的。常见后果包括:

    • 定义的行为就像n 有一些小值,可能为零,然后以下代码尝试将值存储在数组中,但超出了为其保留的内存,从而破坏了程序所需的其他数据。李>
    • 定义表现得好像n 有一些较大的值,导致堆栈溢出并终止程序。

    例如,将 0 存储到 fibs[0] 或将 1 存储到 fibs[1] 可能会写入为 n 保留的内存。然后for 循环终止而不执行任何迭代,因为测试i &lt; n 为假。

    【讨论】:

      猜你喜欢
      • 2020-08-04
      • 1970-01-01
      • 2012-12-17
      • 2013-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      相关资源
      最近更新 更多