【问题标题】:cannot display the result of each one of my function无法显示我的每个功能的结果
【发布时间】:2012-03-26 20:38:34
【问题描述】:

我编写了一个代码,用于计算随机填充 0 到 1 之间值的数组的组件总和。我必须编写两个函数,一个是迭代的,另一个是递归的。两者都应该做同样的工作。当我一次只调用一个时,我编写的两个函数运行良好。但是,如果我尝试在主函数中调用这两个函数,我只能看到一个的结果,而看不到另一个的结果。此外,我的递归函数往往会被调用一次。我注意到如果我将 getch() 作为注释放在 recursive_function() 中。我知道我错过了一些东西,但我无法弄清楚。谢谢你的帮助。这是代码。我正在使用 Dev-C++。

#include <iostream>
#include<conio.h>
#include <stdlib.h>

using namespace std;

//headers of the thre functions
int random_value(int array[], int size);
int iterative_function (int array[], int size, int sum);
int recursive_function ( int size, int array[], int index, int sum);



int main()
{     
   int size;int array[size]; int sum=0;
   int index=0;
   cout<<"enter the size of the array"<<endl;
   cin>>size;                //enter the size ofthe array...
   random_value(array, size);
   iterative_function (array, size, sum); 
   recursive_function ( size, array, index, sum);
   getch();
   return 0;
}

int random_value(int array[], int size)
{  cout<<"here is the value returned by rand()"<<endl;
   for(int i=0;i<size;i++)
   { array[i]=( rand() % (0-2));
     cout<<array[i]<<endl;
   }
}

int iterative_function (int array[], int size, int sum)
{
   int i,j, number, value; i=0;
   cout<<"from the iterative function"<<endl;
   cout<<"------"<<endl;
   for(i=0;i<size;i++)
   sum=sum+array[i];
   cout<<"sum of the array="<<sum<<endl;           
   getch();
   return 0;      //exit the function. Program terminated succesfully.
}

int recursive_function ( int size, int array[], int index, int sum)
{
  if(size>index)
  {  
    sum=sum+array[index];
    index++;
    recursive_function( size, array, index, sum); 
  }
  cout<<"from the recursive function"<<endl;
  cout<<"------"<<endl;
  cout<<"new sum= "<< sum<<endl;

  getch();
  return 0;

}

【问题讨论】:

  • 请注意:您忘记在调用两个函数之间将 sum 变量重置为零。
  • 注意:调试器/跟踪是你的朋友...
  • @KarolyHorvath 注意:单元测试是你的朋友。
  • 我将 sum 变量重置为零,现在,我可以得到每个函数的结果。谢谢约阿希姆。
  • @Karoly / Peter - 想成为你的朋友。接受?是/否(抱歉,无法抗拒)

标签: c++ function recursion iteration


【解决方案1】:
#include <iostream>
#include<conio.h>

&lt;conio.h 不是标准头文件,即它并非适用于所有编译器,您也不需要它。

查看程序的结果输出:

  • 从命令行运行它,或者

  • 在 Visual Studio 中通过按键 [Ctrl F5] 运行它(无调试),或

  • main 的右大括号上设置断点,并在调试器下运行它(在 Visual Studio 中,例如通过按键 [F5])。

#include <stdlib.h>

据我所知,您没有使用此标题中的任何内容。但是,它确实提供了符号常量EXIT_SUCCESSEXIT_FAILURE,它们用于main 中的return 语句。例如,写EXIT_SUCCESS 比写0 更清楚,因为很多人误解了0 在这种情况下的含义。

using namespace std;

这适用于短程序或命名空间内。

但是,请记住,短节目通常以不那么短的节目告终。

然后using namespace std; 很容易导致名称冲突,尤其是名称std::distance

//headers of the thre functions
int random_value(int array[], int size);
int iterative_function (int array[], int size, int sum);
int recursive_function ( int size, int array[], int index, int sum);

虽然部分是偏好问题,但在main 之前前向声明函数并没有优势,这是更多工作,有时会导致问题当前向声明与定义不完全匹配时 - 与任何不必要的冗余一样,违反 DRY 原则(不要重复自己)。

相反,只需将函数定义放在 main 之前。

这样也更容易看出什么指的是什么,因为其他人使用的函数必然在那些其他函数之前。

int main()
{     
   int size;int array[size]; int sum=0;

这不应该编译,因为在 C++ 中,只有动态分配的数组的大小在编译时是未知的。

但是,C99 支持具有上述语法的“可变长度数组”a.k.a. VLA,作为语言扩展,g++ 编译器支持。

另一方面,即使是使用 g++ 语言扩展,上面也声明了一个不确定长度的数组,因为size 变量尚未初始化并且具有不确定的值。

p>

对于 g++ 编译器,该值很可能是 0,但它也可以很容易地成为任何其他值。

要关闭 g++ VLA 语言扩展和一些其他语言扩展,请使用以下 g++ 选项:

-pedantic -std=c++0x -Wall

对于标准 C++,您应该使用 C++ std::vector&lt;int&gt; 而不是 C99 VLA。

为了获得std::vector类模板的声明,包括标准库头&lt;vector&gt;

   int index=0;
   cout<<"enter the size of the array"<<endl;
   cin>>size;                //enter the size ofthe array...

当您使用std::vector 时,知道它的大小,就可以在这里声明该向量。

或者,如果之前声明过,这里就是调整大小的地方。

   random_value(array, size);

这最好是一个返回随机值向量的函数。

然后您将使用它来初始化声明的向量。

   iterative_function (array, size, sum); 
   recursive_function ( size, array, index, sum);
   getch();

关于getch()调用,见上面关于&lt;conio.h&gt;的cmets。

   return 0;

这里关于0的值,见上面关于&lt;stdlib.h&gt;的cmets。

}

int random_value(int array[], int size)
{  cout<<"here is the value returned by rand()"<<endl;
   for(int i=0;i<size;i++)
   { array[i]=( rand() % (0-2));

这里有未定义的行为,访问可能为零大小的数组的元素。

     cout<<array[i]<<endl;
   }
}

int iterative_function (int array[], int size, int sum)
{
   int i,j, number, value; i=0;
   cout<<"from the iterative function"<<endl;
   cout<<"------"<<endl;
   for(i=0;i<size;i++)
   sum=sum+array[i];

在这里,您通过访问不存在的数组元素再次调用未定义行为,通常称为“UB”。

此外,即使数组的大小不为零,它也没有被初始化,因此只会包含零或任意值(根据神圣标准称为“不确定值”)。

   cout<<"sum of the array="<<sum<<endl;           
   getch();

查看上面关于&lt;conio.h&gt;的评论。

   return 0;      //exit the function. Program terminated succesfully.
}

让上述函数总是返回相同的值是没有意义的。从信息论的角度来看,该返回值携带零位信息。而是让函数的结果值为void

int recursive_function ( int size, int array[], int index, int sum)
{
  if(size>index)
  {  
    sum=sum+array[index];
    index++;
    recursive_function( size, array, index, sum); 
  }

不要增加index,这是非惯用的,因此对于有经验的读者来说很难发现,只需在递归调用中使用index + 1

最好将const 添加到几乎所有可能的声明中。

例如,这将迫使您使用index + 1。 :-)

  cout<<"from the recursive function"<<endl;
  cout<<"------"<<endl;
  cout<<"new sum= "<< sum<<endl;

  getch();

查看上面关于&lt;conio.h&gt;的评论。

  return 0;

查看上面关于函数总是返回相同值的注释。

}

总结起来,对于所有未定义的行为,如果事情看起来有效,那只是偶然。

首先修复 UB(特别是用 std::vector 替换 C99 VLA),然后如果它仍然不能正常工作,可以提出新问题。 ;-)

【讨论】:

  • 好的,我会按照您的建议修复这些错误。感谢您进行深入而出色的分析。但是我仍然使用递归函数多次显示相同的显示。我看不出我做错了什么,但我知道我的代码有问题。非常感谢!
【解决方案2】:

您使用 size 创建数组,但在此之后对其进行了初始化。你只是得到随机的东西...... 声明 int 指针,读取大小,用new 分配数组然后再试一次(不要忘记delete)。

【讨论】:

    【解决方案3】:

    首先你声明的数组是未知大小的,在得到大小输入后声明数组

    【讨论】:

      【解决方案4】:

      请记住,在 recursive_function() 中它会多次调用自身 - 每次 调用它(通过 main() 或自身)它都会运行 所有 命令在它的身体里(因为你永远不会早早回来)......现在你能看到里面的 getch() 有问题吗?

      【讨论】:

      • 在递归函数中我仍然没有看到 getch() 的问题。我认为递归函数中的 if(size>index) 应该通过避免递归函数调用自身超出预期来处理该问题。
      • 这并不是因为它导致函数被调用的次数超出预期 - 而是 每次 它被调用时它等待一个按键,而不是首先完成它的所有递归然后在最后等待一个按键,这就是我怀疑你想要的。
      • 没错,但即使我使用了 getch(),我仍然有多次相同的显示,而实际上我希望在所有递归发生后只有一个显示。
      • 与其尝试在每个函数中显示结果,为什么不让函数返回总和,并让主代码显示这些结果?从内部调用 recursive_function() 时,您可以简单地忽略它返回的内容 - 只有 main() 调用的那个才关心它返回的总和。
      • 这是个好主意,但是作业的第二部分要求我们测量每个函数的执行时间差异。这就是为什么我希望在每个函数中都有结果,然后我将计算并比较它们的执行时间。
      猜你喜欢
      • 2021-04-17
      • 2016-10-24
      • 2015-11-16
      • 2016-06-12
      • 1970-01-01
      • 1970-01-01
      • 2020-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多