web-dev-qa-db-ja.com

奇数/偶数再帰関数におけるセグメンテーション障害

再帰関数を使用して、数値が偶数または奇数かを見つけるために、次のコードを書きました。

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

}
 _

コードは正常にコンパイルされますが、セグメンテーション障害が発生します。

その考えは何ですか?

1
el_noobito

目標が、再帰が理想的な解決策ではないことを目標を示すことがない限り、数が偶数または奇数かを判断する機能は再帰的に実装する貧困候補である。

再帰的なソリューションには基本ケースが必要です。それ以外の場合は、システムがリソースを消費し、プログラムがクラッシュするまで自分自身を呼び出します。

数値が偶数または奇妙なかどうかを判断するにはどうすればよいですか。 1つの方法は、-1,0、または1(当社の基本ケース)になるまで、数から2つを徐々に追加または減算することです。

// 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);
    }
}
 _
1
Govind Parmar

コードが原因でセグメンテーション障害が発生しているため、スタックオーバーフロー

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

再帰的な関数がそれ自体を呼び出すたびに、新しい呼び出しの引数を含むスタックに新しいアクティベーションレコードが追加されます。

この再帰関数は、それが2によって割り切れられているかどうかを判断する必要があり、それをするためには、その関数を評価するために呼び出す必要があります。これは、プログラムがスタックから実行されるまで繰り返されます。

0
Mode77