【问题标题】:what does int numbers[n+2]; statement do?int numbers[n+2]; 是什么?声明吗?
【发布时间】:2020-08-24 07:12:35
【问题描述】:
  #include<iostream>

    int fastFibonacci(int n) 
    {
      int numbers[n+2]; // int numbers[n].
      numbers[0] = 0;
      numbers[1] = 1;
      for (int i = 2; i <= n; i++)
      {
          numbers[i] = numbers[i - 1] + numbers[i - 2];
      }
      return numbers[n];
    }

    int main() {
      int n;
      std::cout << "Enter a Number";
      std::cin >> n;
      int result = fastFibonacci(n);
      std::cout << result << "\n";
      return 0;
    }

在此代码中,当我输入输入 0 或 1 时得到正确答案。但问题是,当我用注释部分替换 int numbers[n+2]; 时,当输入为 0 或 1 时,它开始给我错误的答案。为什么?任何人请解释我。

【问题讨论】:

  • 声明可变长度数组是一个非标准的 C++ 特性。这只是一个糟糕的代码,仅此而已。:)
  • 好的,我明白了,但你能解释一下这个声明 int numbers[n+2];
  • 在这段代码中,当我输入 0 或 1 时得到正确答案。 -- 你很幸运,因为这段代码并不能为 Visual Studio 编译,因为非标准 C++ 语法。
  • @Desg Aman 这是一个包含 n + 2 个元素的数组的声明。
  • 哦,好的,感谢您的帮助,我是初学者,所以这就是为什么我会犯错误希望好的,非常感谢您的帮助

标签: c++ fibonacci function-definition


【解决方案1】:

int numbers[n+2];ints 数组的声明,其中包含 n + 2 ints、this is a variable lenght array and is not part of C++ standard 的空格,尽管有些编译器允许它不是你应该使用的东西。

如果您需要可变长度数组,请使用std::vector

对于int numbers[n+2];,如果n 等于0,则仍有2 个ints 的空间,如果有int numbers[n];,则数组将有0 个ints 的空间,因此代码将失败,因为您正在尝试访问 numbers[0]numbers[1] 不存在的内存。

有几种实现斐波那契数列的好方法,在网站上你可以找到很多关于这件事的几种编程语言的问题,这里是其中之一Fibonacci series in C++

编辑

所以我看到你的 cmets 关于使用向量,为了制作序列,你不需要向量只需要两个变量来存储两个要相加的数字,将序列存储在 vactor 中,你可以做类似的事情:

#include <iostream>
#include <vector>
#include <iomanip>

//passing the vector by reference
void fastFibonacci(unsigned long long n, std::vector<unsigned long long>& sequence) {

   unsigned long long first = 0;
   unsigned long long second = 1;
   sequence.push_back(first); //add first values to the vector
   sequence.push_back(second); //add first values to the vector
   for (unsigned long long i = 0, value = 0; i < n && value <= LLONG_MAX ; ++i) {
      value = first + second;
      first = second;
      second = value;
      sequence.push_back(value); //adding values to the vector
   }  
}

int main() {  
   unsigned long long limit; //number of values in the sequence
   int num = 1;
   std::vector<unsigned long long> sequence; //container for the sequence

   std::cout << "Enter upper limit: ";
   std::cin >> limit;
   fastFibonacci(limit, sequence);

   //print the sequence in a range based loop formatted with <iomanip> library
   for(auto& i : sequence){
      std::cout << std::setw(4) << std::left << num++ << " " << i << std::endl; 
   }
   return 0;
}

如果您只想打印序列中的一个数字,只需使用,例如:

std::cout << sequence[10];

而不是整个向量。

您在另一个答案的评论中发布的代码将不起作用,因为对矢量的访问超出了numbers[i] = numbers[i - 1] + numbers[i - 2]; 的范围,例如i = 5,您的矢量只有 2 个节点,但您正在访问第6个节点numbers[5]

【讨论】:

  • @DesgAman,不客气,我添加到答案中是为了解决您关于int numbers[n]; 的问题。
  • @DesgAman,我在另一个答案中看到了您的评论,我发布了一个可能的解决方案以及新代码格式错误的原因,希望对您有所帮助,如果您有任何疑问可以问.
【解决方案2】:

在这个函数中

int fastFibonacci(int n) 
{
  int numbers[n+2]; // int numbers[n].
  numbers[0] = 0;
  numbers[1] = 1;
  for (int i = 2; i <= n; i++)
  {
      numbers[i] = numbers[i - 1] + numbers[i - 2];
  }
  return numbers[n];
}

这里使用了一个可变长度数组,其中声明了n + 2 元素

  int numbers[n+2]; // int numbers[n].

可变长度数组不是标准的 C++ 功能。它可以实现为 C++ 编译器自己的语言扩展。

使用可变长度数组会使函数非常不安全,因为可能会发生堆栈溢出。

在函数中明确使用了数组的两个元素

  numbers[0] = 0;
  numbers[1] = 1;

那么即使参数的值小于 2,数组也应该至少有两个元素。

要计算第 n 个斐波那契数,不需要声明这样大小的数组。

除此之外,函数参数应具有无符号整数类型。否则,如果用户传递负数,该函数可以调用未定义的行为。

同样对于n 的大值,int 类型可能存在整数溢出。

该功能可以通过多种方式实现。

这是它的一种可能实现方式。

#include <iostream>
#include <functional>

unsigned long long fibonacci( unsigned int n )
{
    unsigned long long a[] = { 0, 1 };

    while ( n-- )
    {
        a[1] += std::exchange( a[0], a[1] );
    }

    return a[0];
}

int main() 
{
    const unsigned int N = 10;

    for ( unsigned int i = 0; i < N; i++ )
    {
        std::cout << i << ": " << fibonacci( i ) << '\n'; 
    }

    return 0;
}

程序输出是

0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34

【讨论】:

  • 谢谢。你能告诉我这次我做对了吗int fastFibonacci2(int n) { std::vector&lt;unsigned long int&gt; numbers; numbers.push_back(0); numbers.push_back(1); for (int i = 2; i &lt;= n; i++) { numbers[i] = numbers[i - 1] + numbers[i - 2]; } return numbers[n]; }
  • @DesgAman 你为什么问我?您已经选择了最佳答案。 std::vector 的想法很糟糕。这种方法效率低下。我在回答中展示了如何更简单地实现该功能。并且由您提供的代码具有未定义的行为,因为您不能将下标运算符与向量的不存在的元素一起使用。
  • 我问你是因为我发现你的回答也很有帮助。这并不意味着如果我选择了最佳答案,您的答案就不好。感谢您对我的帮助。
猜你喜欢
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
  • 2020-02-23
  • 2012-07-12
相关资源
最近更新 更多