奇/偶递归函数中的分段错误
Posted
技术标签:
【中文标题】奇/偶递归函数中的分段错误【英文标题】:Segmentation fault in odd/even recursive function 【发布时间】:2022-01-12 14:46:58 【问题描述】:我编写了以下代码,以便使用递归函数查找数字是偶数还是奇数。
#include <stdio.h>
#include <stdlib.h>
int posneg(int n)
if (posneg(n-1)%2 == 0)
return 1;
else
return 0;
main ()
int num;
do
printf("Provide a number");
scanf("%d",&num);
while (num <= 0);
if (posneg(num) == 1)
printf("The number is even");
else
printf("The number is odd");
代码编译成功,但出现分段错误。
任何想法是什么原因?
【问题讨论】:
你的 posneg 函数的递归什么时候停止? "posneg" 是偶数还是奇数?令人着迷。 当数字是奇数或偶数时 整数总是奇数或偶数,所以你是说posneg函数永远不会递归? 尝试手动跟踪逻辑。你会看到它永远不会停止。您需要在递归调用之前测试n
。
【参考方案1】:
您遇到分段错误,因为您的代码导致堆栈溢出。
int posneg(int n)
if (posneg(n-1)%2 == 0)
return 1;
else
return 0;
每次递归函数调用自身时,都会将新的激活记录添加到包含新调用参数的堆栈中。
这个递归函数永远不会评估基本情况,因为它必须确定它是否可以被 2 整除,为了做到这一点,你必须调用函数来评估它。重复此操作,直到您的程序用完堆栈。
【讨论】:
【参考方案2】:确定一个数是偶数还是奇数的函数不适合递归实现,除非目标是说明递归通常不是理想的解决方案。
递归解决方案必须有一个基本情况,否则它将继续调用自己,直到系统耗尽资源并且程序崩溃。
如何递归判断一个数是偶数还是奇数?一种方法是从数字中逐渐加或减 2,直到我们得到 -1、0 或 1(我们的基本情况):
// Let's say a return value of '1' means odd and '0' means even
int evenodd (int n)
if(-1 == n || 1 == n) // base case: n is odd
return 1;
else if(0 == n) // base case: n is even
return 0;
else
return evenodd(n > 0 ? n-2 : n+2);
【讨论】:
@ikegami 当 n == INT_MIN 时会导致 UB。坏主意。 0___________,好的,if (n > 0) n = -n;
然后 :) 但这感觉很奇怪。【参考方案3】:
对于根据 C 标准的初学者,不带参数的函数 main 应声明为
int main( void )
你不能省略函数的返回类型。
其次,如果您期望一个非负数,则将变量 num
声明为具有 int
类型没有什么意义。该变量应声明为具有unsigned int
类型。
由于函数内部的 if 语句,函数会产生无限递归
int posneg(int n)
if (posneg(n-1)%2 == 0)
return 1;
else
return 0;
使用您定义函数的方法,它可以如下面的演示程序所示,例如以下方式
#include <stdio.h>
int posneg( unsigned int n )
return ( n == 0 ) || ( ( 1 + posneg( n - 1 ) ) % 2 );
int main( void )
while ( 1 )
printf( "Provide a non-negative number (0 - exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
if ( posneg( n ))
printf( "The number %u is even.\n", n );
else
printf( "The number %u is odd.\n", n );
程序输出可能看起来像
Provide a non-negative number (0 - exit): 1
The number 1 is odd.
Provide a non-negative number (0 - exit): 2
The number 2 is even.
Provide a non-negative number (0 - exit): 3
The number 3 is odd.
Provide a non-negative number (0 - exit): 4
The number 4 is even.
Provide a non-negative number (0 - exit): 5
The number 5 is odd.
Provide a non-negative number (0 - exit): 6
The number 6 is even.
Provide a non-negative number (0 - exit): 7
The number 7 is odd.
Provide a non-negative number (0 - exit): 8
The number 8 is even.
Provide a non-negative number (0 - exit): 9
The number 9 is odd.
Provide a non-negative number (0 - exit): 0
【讨论】:
以上是关于奇/偶递归函数中的分段错误的主要内容,如果未能解决你的问题,请参考以下文章