odd/even 递归函数中的分段错误

Segmentation fault in odd/even recursive function

我编写了以下代码,以便使用递归函数查找数字是偶数还是奇数。

#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");

}

代码编译成功,但出现分段错误。

知道这是什么原因吗?

您遇到了分段错误,因为您的代码导致了堆栈溢出

int posneg(int n){ 
        
    if (posneg(n-1)%2 == 0){
        return 1;
    }
    else {
        return 0;
    }
}

递归函数每次调用自身时,都会将新的激活记录添加到包含新调用参数的堆栈中。

此递归函数永远不会计算基本情况,因为它必须确定它是否可以被 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);
    }
}

对于根据 C 标准的初学者,不带参数的函数 main 应声明为

int main( void )

您不能省略函数的 return 类型。

其次,如果您期望一个非负数,那么将变量 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