I wrote the following code in order to find whether a number is even or odd using a 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");
}
The code compiles successfully but I get a Segmentation Fault.
Any ideas what is the cause of that?
CodePudding user response:
A function to determine whether a number is even or odd is a poor candidate to implement recursively, unless the goal is to illustrate that oftentimes recursion is not an ideal solution.
A recursive solution must have a base case, otherwise it will continue calling itself until the system runs out of resources and the program crashes.
How can we determine if a number is even or odd recursively? One way is to gradually add or subtract two from the number until we get to -1, 0, or 1 (our base cases):
// 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);
}
}
CodePudding user response:
You're getting a segmentation fault because you're code is causing a stack overflow.
int posneg(int n){
if (posneg(n-1)%2 == 0){
return 1;
}
else {
return 0;
}
}
Every time a recursive function calls itself, a new activation record is added to the stack containing the arguments of the new call.
This recursive function will never evaluate to the base case because it has to determine whether it's divisible by 2, and in order to do that, you have to call the function to evaluate it. This is repeated until your program runs out of stack.
CodePudding user response:
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
You may not omit the return type of the function.
Secondly there is no great sense to declare the variable num
as having the type int
if you expect a non-negative number. The variable should be declared as having the type unsigned int
.
The function produces an infinite recursion due to the if statement inside the function
int posneg(int n){
if (posneg(n-1)%2 == 0){
return 1;
}
else {
return 0;
}
}
Using your approach of defining the function it can look for example the following way as it is shown in the demonstrative program below
#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 );
}
}
}
the program output might look like
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