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
我编写了以下代码,以便使用递归函数查找数字是偶数还是奇数。
#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