I wrote a C program to use recursive functions to find the factorial of a number and the code is given below:
//program to find factorial of a number using a recursive function
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int factorial(int a);
int main()
{
int num, fact;
printf("Enter a number: ");
scanf("%d", &num);
if(num<=0)
{
printf("The number cannot be zero/negative.");
exit(1);
}
fact=factorial(num);
printf("The factorial of the entered number is: %d", fact);
getch();
return 0;
}
int factorial(int a)
{
while(a>1)
return a*factorial(--a);
}
In the above code in 'while' loop if the input 'a'>1 then it should execute, but when i compile the program (using Dev C++ v.5.4.2) and give the input as 1, I get the factorial as 1. The program is the solution to the required problem, but i need to know what is actually happening in background...
Thank you in advance
int factorial(int a)
{
while(a>1)
return a*factorial(--a);
}
This function does not return anything if the condition in while loop is not true. Thus , invoking undefined behaviour (Maybe giving you correct output).
You should handle that case -
int factorial(int a)
{
if(a==1)return 1;
//while(a>1) // you use recursion then why using loop
return a*factorial(a-1);
}
In the case where a <= 1 your function does not have a return statement, even though it expects one. Which means you have a bug which will invoke undefined behavior: anything can happen, including: "seems to work ok", "weird output", the program crashes etc.
A half-decent compiler would warn you for this. For example GCC with warnings enabled:
warning: control reaches end of non-void function [-Wreturn-type]|
This is undefined behavior.
N1256 6.9.1 Function definitions
12 If the } that terminates a function is reached, and the value of the function call is used by
the caller, the behavior is undefined.
To know what is actually happening in this specific situration, have your compiler output assembly code and read it, or use debugger suce as OllyDbg.
Your compiler seems to allow omission of return value. What happens is that your "factorial" function will not execute the while() loop, and after the while loop there is no return statement, so the return value will be undefined.
int factorial(int a)
{
while (a>1) // a is 1 so this will be false, and the loop will not execute
return a*factorial(--a);
return 1; // this value will be returned
}
Also, I suggest you review this code (looks like a school exercise to me). Currently, although it may work correctly, the code differs from how an experienced programmer would implement it.
Related
I came across a question in a test series, which when I solved manually according to my knowledge of C programming, should give an output which wasn't matching with any of the options given.
My output = ' ++++ '
Question: Output of following c program is?
#include <stdio.h>
int f(int x)
{
if(x==2){ return 2; }
else{ printf("+"); f(x-1); }
}
int main()
{
int n = f(6);
printf("%d",n);
return 0;
}
Options:
'++++2' (correct option acc to answer key)
'+++++2'
'+++++'
'2'
My logic: Because in the end f(6) doesn't explicitly return anything [only f(2) returns the value 2 to f(3)], the output should only contain the 4 times '+' due to each call f(6), f(5), f(4) and f(3).
Below are some test code and their outputs screenshots i tried on online c compilers - 'codechef' and 'onlinegdb' - but i couldnt make sense of their outputs either. Please help!
codechef
onlinegdb 1
onlinegdb 2
If a function is defined to return a value and it doesn't, then attempting to use the returned value results in undefined behavior.
This is documented in section 6.9.1p12 of the C standard:
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
This basically means that the result is not predictable and/or consistent.
So I've written a function that should return the n'th Fibonnacci number, but I forgot to actually return my result. I did get the " control reaches end of non-void function" warning, but the code executed fine and returned the correct result. Why is that? How does C know that it should return "result"?
int fib (int n);
int main(int argc, char** argv) {
printf("%d", fib(10));
}
int fib (int n){
if (n == 1){
return 1;
}
if (n == 0){
return 0
}
fib(n-2) + fib(n-1)
}
It returned this
55
I've tried to add
int j = n+1
to the last line of the function, and then it actually returned 2, not 256. Is this a bug, or how does c read something like this?
Reaching the end of a non void function without a return statement invokes undefined behavior. Getting the expected result is a form of undefined behavior commonly called luck. By the way, 256 may be what you expected, but it is not correct.
A possible explanation is: the last value computed by the function and stored into the register that would normally contain the return value is the expected result.
Of course you should never rely on this, nor expect it.
This is a good example of the use of compiler warnings: do not ignore them. Always turn on more compiler warnings and fix the code. gcc -Wall -W or clang -Weverything can spot many silly mistakes and save hours of debugging.
Here are some other problems:
you do not include <stdio.h>
you compute an unsigned long long but only return a probably smaller type int
your algorithm computes powers of 2, not Fibonacci numbers.
#include<stdio.h>
int GetPositiveInt(void);
int main(void)
{
int num = GetPositiveInt();
printf("%d",num);
return 0;
}
int GetPositiveInt(void)
{
int n;
do
{
printf("Enter a positive number : ");
scanf("%d",&n);
}while(n<=0);
}
The output is the value of n but I don't know how it is returned to num.
Does scanf() and printf() affect the return value of a function?
If I add a statement like printf("%d",7); after while then the output is 71,no idea how 1 comes.
This is my output. This is for reference only .
Text as requested :-
usr#usr:~/C_programs$ gcc -std=c99 return.c -o return
usr#usr:~/C_programs$ ./return
Enter a positive number : 45
45usr#usr:~/C_programs$ ./return
Enter a positive number : 89
89usr#usr:~/C_programs$
TL;DR Your code produces undeifined behavior.
You're missing a return statement in GetPositiveInt() function. Without having an explicit return statement to return a value, collecting the return value of the function call in the caller function and using that leads to undefined behaviour.
Ref: As per the C11 standard document, chapter ยง6.9.1,
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
FWIW, only in case of main() , addition of return statement is not mandatory. From same document, chapter 5.1.2.2.3, for main() function
reaching the } that terminates the main function returns a value of 0.
In the following function:
int GetPositiveInt(void)
{
int n;
do
{
printf("Enter a positive number : ");
scanf("%d",&n);
}while(n<=0);
}
the function is expected to return an int value, whereas there is no return statement. You probably wanted to return the value of n. This can be achieved by adding the suitable return statement:
return n;
Like this:
int GetPositiveInt(void)
{
int n;
do
{
printf("Enter a positive number : ");
scanf("%d",&n);
}while(n<=0);
return n;
}
no idea how '1' comes.
Because you did not return anything in your method GetPositiveInt - and the behavior is undefined:
int GetPositiveInt(void)
{
int n;
do
{
printf("Enter a positive number : ");
scanf("%d",&n);
}while(n<=0);
return n; //<---Add this line
}
C99 6.9.1/12 "Function definitions" says:
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
It prints 0 for me.
As explained in the other answers, the lack of the return statement in a function that is declared to return something is signaled by the compiler with a warning but the generated code exposes undefined behaviour. This means the function can return any value, the compiler cannot guarantee anything about it.
You can think of the value returned by a function as a hidden local variable of that function. Since the return statement is missing, the hidden variable is not initialized and its value is whatever garbage data happened to be in the memory at the time when the function was called.
In practice, the return statement is translated into a processor instruction that copies the returned value into one of the general-purpose processor's registries (usually %eax on x86). The calling function (main() in your code) gets the values from that register and uses it.
Because your function GetPositiveInt() does not contain a return statement, the compiler skips generating the instruction that puts the correct value in %eax and the function completes its execution letting in %eax whatever value happened to be there as a result of earlier processing.
This is a case of undefined behaviour because you are missing the return statement.however I can explain why 1 is coming.
The printf function returns the number of characters printed by it.For example
printf("%d",printf("%d",7));
first printf prints 7 and returns 1 as number of characters printed. So output is 71.
#include<stdio.h>
#int add(int n);
int main()
{
int n;
printf("Enter an positive integer: ");
scanf("%d",&n);
printf("Sum = %d",add(n));
return 0;
}
int add(int n)
{
if(n!=0)
return n+add(n-1); /* recursive call */
}
How will this code executed without having a base case like if(n==0){return 0;}?
Without a base case you are creating code with undefined behaviour. Your compiler will issue a warning saying that your function that returns int does not have a return statement. This does not mean that the function that called it won't look for a returned value which may or may not contain garbage.
You're going to run into problems here: add will only return a value if n != 0, so if n <= 0, you won't have a value returned, so when add calls itself with n-1 passed in, you'll eventually reach your base case that doesn't exist, and bad things will happen.
if(n==0){return 0;}
is the base case. The base case exists to get the recursion to stop. Without a base case you will just infinitely recurse until you possibly hit some kind of error. In your case it will start adding negative numbers.
From the C standards:
Flowing off the end of a function is equivalent to a return with no
value; this results in undefined behavior in a value-returning
function.
Your compiler may warn you:
not all control paths return a value
It's the same situation with this one.
This is calling convention and architecture dependent. The return value is the result of last expression evaluation, stored in the eax register. So when n==0, you function add() returns 0, but it's a result of undefined behavior.
I have a recursive program. When the printf is used in the function, it outputs 123 and when used outside, it outputs 0123 .
#include <stdio.h>
fact(int);
int main()
{
int x=3;
fact(x);
printf("\n");
system("PAUSE");
}
int fact(int y)
{
if (y > 0)
{
fact(y-1);
printf("%d",y);
}
//printf("%d",y);
}
I am not using both the printf at the same time . What difference does the location of this printf statement create?
Since your if condition looks for the values greater than zero, it is working as expected.
When the printf outside that IF block is used, it gets executed even when y is 0, which is not the case for the printf inside the IF block.
fact(int) is called by following sequence,
fact(3)-->fact(2)--->fact(1)--->fact(0)
The last call is fact(0). According to the implementation of fact(int), when 0 is passed in, 0 is printed if printf() is used outsite. 0 is not printed if printf() is used inside.
In fact, all the values passed into fact(int) is printed when printf() is used outsite.
I'd say one reason you didn't see the answer yourself is because your code is sloppy. Here are some complaints:
Your functions have no explicit return statements which are
especially important for understanding recursive code.
system() requires stdlib, but stdlib.h isn't included.
system("PAUSE") is unportable and unnecessary. Actually your code
would not run on my system because of this. See:
http://www.gidnetwork.com/b-61.html
Your question looks like homework, so this one is the homework's fault and not yours: because n! grows so quickly, factorial functions using 'int' for the return type can only calculate n! for 1<=n<=12, which is useless.
Try this exercise: write a one-line factorial function using a single return and a conditional assignment.