Can anyone tell me the reason of getting 0 1 2 0 as output of below program?
#include <stdio.h>
main() {
e(3);
}
void e(int n) {
if(n>0) {
e(--n);
printf("%d",n);
e(--n);
}
}
Output is 0 1 2 0
Here' the flow of execution after e(3) is called from main.
e(3)
e(2)
e(1)
e(0) ... return
n is now 0
print n. results in output 0
e(-1) ... return
n is now 1
print n. results in output 1
e(0) ... return
n is now 2
print n. results in output 2
e(1)
e(0) ... return
n is now 0
print n. results in output 0
e(-1) ... return
return
And you see the output
0 1 2 0
I'm assuming the following is what you want:
#include <stdio.h>
void e(int);
int main()
{
e(3);
return 0;
}
void e(int n)
{
if(n > 0) {
e(--n);
printf("%d", n);
e(--n);
}
}
This is an example of a recursive function - a function calling itself. Here, at each call the parameter is decremented and the function is again called until the condition n > 0 is not met. Then, the printf("%d", 0) happens. Now the second e(--n) will have no effect until n is at least 2, since the if condition cannot be passed with a value of n less than 1. Further printf()s happen in the reverse order of the call as the function calls are removed from the stack. When the value gets to 2, the second e(--n) gets a chance to make an effect thus printing 0.
You need to learn about recursion (if you still haven't) and then you can get a good picture of how things happen. Also, it will help you if learn more about how the stack is set up when a function is called, and later returned.
The 'flow' goes as follows:
main -> e(3)
e(3) -> IF(3>0)
{
// n is pre-decremented to 2
e(2) -> IF(2>0)
{
// n is pre-decremented to 1
e(1) -> IF(1>0)
{
// n is pre-decremented to 0
e(0) -> 0 is not > 0 so this call does nothing.
// n is still 0 in this function call so...
printf(0) <-- The first '0' in the output
// n is pre-decremented to -1
e(-1) -> -1 is not > 0) so this call does nothing.
}
// n is still 1 in this function call so...
printf(1) <-- The '1' in the output
// n is pre-decremented to 0
e(0) -> 0 is not > 0 so this call does nothing
}
// n is still 2 in this function call so...
printf(2) <-- The '2' in the output
// n is pre-decremented to 1
e(1) -> (1 is > 0)
{
// n is pre-decremented to 0
e(0) -> 0 is not > 0 so this call does nothing
// n is still 0 in this function call so...
printf(0) <-- The second '0' in the output
// n is pre-decremented to -1
e(-1) -> -1 is not > 0 so this call does nothing
}
}
It helps if you set the code out more clearly:
#include<stdio.h>
main()
{
e(3);
}
void e(int n)
{
if(n>0)
{
e(--n); // First recursion here, but with n=n-1 on entry to the call.
printf("%d",n); // outputs (original value of n) - 1.
e(--n); // Second recursion here, now with n=n-2 on entry to the call.
}
}
After denesting the code the reason for the results can be deduced in a single run in a debugger.
e() is recursive and called once before the print and once after. So before you hit your print statement you'll have to go through e again, and again, and again till it finally hits 0.
After that things start unlooping and you'll see prints popping up but it's still a big recursive mess because of the second call to e(n) in which n dips into the negative. I was rather grateful n was signed because if it was unsigned it would loop round to 2^32 and the program would get stuck in, pretty much, an infinite loop.
So yeah, TL;DR: run it through a debugger and learn from the FUBAR a recursion like this can cause.
Related
Without using an array, I am trying to do this. what is wrong with my code?
n is the number of elements,a is the first element(assumed to be maximum initially), b stores new element every time and sec variable stores the second-largest element. Numbers are all positive. This is from an online contest.
#include<stdio.h>
int main() {
int i,a,b,max,n,sec;
scanf("%d",&n);
scanf("%d",&a);
max=a;
while(n-1!=0) {
scanf("%d",&b);
if(b>max) {
sec=max;
max=b;
}
else if(b<max && b>sec)
sec=b;
else{}
n--;
}
printf("%d",sec);
return 0;
}
getting wrong answers in some test cases( i don't know )
Consider sequence 2, 12, 10 (leaving out surrounding code):
int sec; // unitialised!!!
max = a; // 12
if(b > max) // b got 10, so false!
{
sec = max; // this code is not hit! (b remains uninitalised)
max = b;
}
else if(b < max && b > sec)
// ^ comparing against uninitialised
// -> UNDEFINED BEHAVIOUR
You need to initialise sec appropriately, e. g. with INT_MIN (defined in <limits.h>); this is the minimal allowed value, with 32-bit int that would be a value of -232 - 1, i. e. -2 147 483 648. Pretty unlikely anybody would enter that value, so you could use it as sentinel.
You even could initialise max with that value, then you woudn't need special handling for the first value:
int sec = INT_MIN, max = INT_MIN;
int n;
scanf("%d", &n); // you should check the return value, which is number of
// successfully scanned values, i. e. 1 in given case,
// to catch invalid user input!
// you might check value of n for being out of valid range, at very least < 0
while(n--) // you can do the decrement inside loop header already...
{
// keep scope of variables as local as possible:
int a;
// scanf and comparisons as you had already
// again don't forget to check scanf's return value
}
if(sec == INT_MAX)
{
// likely hasn't been modified -> error, no second largest element
}
else
{
// ...
}
Now what if you do expect user to give you the value of INT_MIN as input?
You could have a separate counter, initialised to 0, you increment in both of the two if branches inside the loop; if this counter is < 2 after the loop, you didn't get at least two distinct numbers...
Lets look at the input
2 4 3
Two is the number of inputs.
4 ends up in max.
3 ends up in b.
b is not greater than max, the if does not do anything.
b is less than max, but b is not necessarily greater than sec,
because sec at this point can be anything - whatever currently is inside that non-initialised variable. sec at this point is for example not guaranteed to be 0. So the else if does not trigger and we end up in else {}.
So we end up executing the printf() at the end of the program with a still uninitialised sec. And that is unlikely to satisfy the judge.
To solve the problem, you need to initialise sec. Initialising to 0 might work, but actually you need to use the lowest possible input value.
Since you chose int, instead of unsigned int, I assume that 0 is NOT the lowest possible value. But you would have to quote the assignment/challenge to allow determining the lowest possible value. So you need to find that out yourself in order to make a solution code.
Alernatively, you can analyse the first input values to initialise max and sec (need to watch them coming in until you get two distinct values; credits to Aconcagua).
Usually it is however easier to determine the lowest possible value from requirements or the lowest possible int value from your environment.
At some level of nitpicking, you need to know the lowest possible value anyway, in order to select the correct data type for your implementation. I.e. even with analysing the first two values, you might fail for selecting the most narrow data type.
In case you "successfully" (as judged by the challenge) use 0 to initialise sec, try the input 2 1 -1.
It should fail.
Then try to find in your challenge/assignment description a reason why using 0 is allowed. It should be there, otherwise find a different challenge site to improve your coding skills.
I liked how OP initialized max with the first input value.
This brought me to the idea that the same can be done for sec.
(The value of max is a nice indicator that sec could not be determined whatever max contains. In regular case, max and sec can never be equal.)
Hence, one possibility is to initialize max and sec with the first input
and use max != sec as indicator whether sec has been written afterwards at all.
Demo:
#include <stdio.h>
int main()
{
/* read number of inputs */
int n;
if (scanf("%d", &n) != 1 || n < 1) {
fprintf(stderr, "ERROR!\n");
return -1;
}
/* read 1st input */
int max;
if (scanf("%d", &max) != 1) {
fprintf(stderr, "ERROR!\n");
return -1;
}
--n;
int sec = max;
/* read other input */
while (n--) {
int a;
if (scanf("%d", &a) != 1) {
fprintf(stderr, "ERROR!\n");
return -1;
}
if (max < a) { sec = max; max = a; }
else if (sec == max || (sec < a && a < max)) sec = a;
}
/* evaluate result */
if (sec == max) {
puts("No second largest value occurred!\n");
} else printf("%d\n", sec);
/* done */
return 0;
}
Output:
$ gcc -std=c11 -O2 -Wall -pedantic main.c
$ echo -e "3 3 4 5" | ./a.out
4
$ echo -e "3 3 5 4" | ./a.out
4
$ echo -e "3 4 3 5" | ./a.out
4
$ echo -e "3 4 5 3" | ./a.out
4
$ echo -e "3 5 3 4" | ./a.out
4
$ echo -e "3 5 4 3" | ./a.out
4
$ # edge case:
$ echo -e "2 3 3" | ./a.out
No second largest value occurred!
Live Demo on coliru
void prikaz(int k, int n)
{
printf("%d\t",k);
if(k<n)
prikaz(k+1,n);
printf("%d\t",k);
}
prikaz(2,6);
I cant wrap my head around the output of this recursive loop, i can follow through till numbers start to descend but i dont understand why they descend.
The reason is because of the last line in the function, which prints the value of k after the recursive call has returned/finished. This will print the value as it was before the +1, i.e. the original value before the call.
However, it only does that part after all the recursive calls are complete.
Basically, when k<n is no longer true, then it will start to do the last printf call, then return to the previous function call and do that ones last printf (which will be the value of k before it was incremented) and it will repeat until all previous calls are complete.
It's quite hard to explain, you just need to step through it more carefully. Using a debugger would help greatly.
Maybe this helps explain it better:
// call 1 (k = 2)
// call 1 print 2
// call 2 (k = 3)
// call 2 print 3
// call 3 (k = 4)
// call 3 print 4
// call 4 (k = 5)
// call 4 print 5
// call 5 (k = 6)
// call 5 print 6
// k<n is false, so no more recursive calls.
// call 5 print 6
// call 4 print 5
// call 3 print 4
// call 2 print 3
// call 1 print 2
In order to learn recursion, I want to count the number of decimal digits that compose an integer. For didactic purposes, hence, I would like to not use the functions from math.h, as presented in:
Finding the length of an integer in C
How do I determine the number of digits of an integer in C? .
I tried two ways, based on the assumption that the division of an integer by 10 will, at a certain point, result in 0.
The first works correctly. count2(1514, 1) returns 4:
int count2(int n, int i){
if(n == 0)
return 0;
else
return i + count2(n / 10, i);
}
But I would like to comprehend the behavior of this one:
int count3(int n, int i){
if(n / 10 != 0)
return i + count3(n / 10, i);
}
For example, from count3(1514, 1); I expect this:
1514 / 10 = 151; # i = 1 + 1
151 / 10 = 15; # i = 2 + 1
15 / 10 = 1; # i = 3 + 1
1 / 10 = 0; # Stop!
Unexpectedly, the function returns 13 instead of 4. Should not the function recurse only 3 times? What is the actual necessity of a base case of the same kind of count2()?
If you do not provide a return statement the result is indeterminate.
On most architectures that mean your function returns random data that happens to be present on the stack or service registers.
So, your count3() function is returning random data when n / 10 == 0 because there is no corresponding return statement.
Edit: it must be stressed that most modern compilers are able to warn when a typed function does not cover all exit points with a return statement.
For example, GCC 4.9.2 will silently accept the missing return. But if you provide it the -Wreturn-type compiler switch you will get a 'warning: control reaches end of non-void function [-Wreturn-type]' warning message. Clang 3.5.0, by comparison, will by default give you a similar warning message: 'warning: control may reach end of non-void function [-Wreturn-type]'. Personally I try to work using -Wall -pedantic unless some required 3rd party forces me to disable some specific switch.
In recursion there should be base conditions which is the building block of recursive solution. Your recursion base doesn't return any value when n==0 — so the returned value is indeterminate. So your recursion count3 fails.
Not returning value in a value-returning function is Undefined behavior. You should be warned on this behavior
Your logic is also wrong. You must return 1 when `(n >= 0 && n / 10 == 0) and
if(n / 10 != 0)
return i + count3(n / 10, i);
else if (n >= 0) return 1;
else return 0;
I don't think you need that i+count() in the recursion. Just 1+count() can work fine...
#include <stdio.h>
#include <stdlib.h>
static int count(), BASE=(10);
int main ( int argc, char *argv[] ) {
int num = (argc>1?atoi(argv[1]):9999);
BASE= (argc>2?atoi(argv[2]):BASE);
printf(" #digits in %d(base%d) is %d\n", num,BASE,count(num)); }
int count ( int num ) { return ( num>0? 1+count(num/BASE) : 0 ); }
...seems to work fine for me. For example,
bash-4.3$ ./count 987654
#digits in 987654(base10) is 6
bash-4.3$ ./count 123454321
#digits in 123454321(base10) is 9
bash-4.3$ ./count 1024 2
#digits in 1024(base2) is 11
bash-4.3$ ./count 512 2
#digits in 512(base2) is 10
Hello everyone I had a tough time understanding recursive function calls and just when I thought I have understood them, I saw a question which made me realized that I am wrong
I am not able to understand the flow of the program
#include <stdio.h>
void fun(int n)
{
if(n>0)
{
fun(--n);
printf("%d\n",n);
fun(--n);
}
}
int main(void) {
int a;
a=3;
fun(a);
return 0;
}
This is the function call for your function when n = 3
f(3)
.f(2) [1]
..f(1) [1]
...f(0) [1]
...Print 0
...f(-1) [2]
..Print 1
..f(0) [2]
.Print 2
.f(1) [2]
..f(0) [1]
..Print 0
..f(-1)[2]
Where . represent the depth of stack and 1 and 2 specify whether its first recursive call from the loop or second.
Because
f(3)
becomes
f(2)
print 2
f(1)
which inturn becomes
f(1)
print 1
f(0)
print 2
f(0)
print 0
f(-1)
Which finally becomes
f(0)
print 0
f(-1)
print 1
f(0)
print 2
f(0)
print 0
f(-1)
Removing all the f(n) when n <= 0
print 0
print 1
print 2
print 0
Let's try to understand it with case n=2 and then you should be able to generalize.
fun (2):
What happens inside (flow):
1) n=2: if(n>0) is true and fun(--n) is called with n set to value 1 due to --; (see step below).
2) n=1: Now n=1: again if(n>0) is true and fun(--n) is called with n=0. See step below.
3) n=0: Now n=0; if(n>0) is false, so we return.
I think here is your confusion. From step 3 you are thrown back
at step 2 (not step 1). You are thrown actually in step 2 after fun(--n) call - so printf is called with value of n=0, due to decrement.
Then again in same place (after printf) fun(--n) is called with value n=-1 however, which will also exit - and eventually you will be thrown at the beginning.
I would draw a "call tree" to help visualize the program.
The function has those parts
decrement n, call, print, decrement n, call
now you can draw this:
0 -1
1->0, print 0, 0->-1, 0
2->1, print 1, 1->0, 1->0, .....
3->2, print 2, 2->1, .....
Start at the bottom left, and go up one line for each call. The program executes from left to right, and you can clearly see the order of the numbers printed.
Here is what happens (pseudocode):
n = 3
fun(3);
n = 2
fun(2); // first fun(--n)
n = 1
fun(1); // first fun(--n)
n = 0
fun(0); // first fun(--n)
return;
print 0
n = -1
fun(-1); // second fun(--n)
return;
return;
print 1
n = 0
fun(0); // second fun(--n)
return;
return;
print 2
n = 1
fun(1); // second fun(--n)
n = 0
fun(0); // first fun(--n)
return;
print 0
n = -1
fun(-1); // second fun(--n)
return;
return;
return;
return;
I believe the cause of confusion is your assumption that the same "n" is used by every call to the function fun(). In fact, that's not the case, since in the C language, argument are passed by value. That is, when fun(3) calls fun(2), a new n is created - specific to one instance of fun(2). Thus after the call to fun(3) within fun(2), the value of n is 2, not or -1.
You should therefore expect...
fun(1) to print 0
fun(2) to print 1
fun(3) to print 2
fun(1) (called from the second call to fun(2)) to print 0
and that's it.
The output of the program can be understood by iteratively expanding the function calls and removing the conditions; in a pseudocode-manner, this can be done as follows.
fun(3)
Can be expanded to the following.
if(3>0)
{
fun(2);
printf("%d\n",2);
fun(1);
}
In the follwing steps, the if condition is omitted if it will evaluate to false.
fun(1);
printf("%d\n",1);
fun(0);
printf("%d\n",2);
fun(0);
printf("%d\n",0);
fun(-1);
The calls to fun with non-positive arguments can be omitted as they will generate no output.
fun(1);
printf("%d\n",1);
printf("%d\n",2);
printf("%d\n",0);
Further expansion yields the following sequence.
fun(0);
printf("%d\n",0);
fun(-1);
printf("%d\n",1);
printf("%d\n",2);
printf("%d\n",0);
This can be again reduced to the following sequence.
printf("%d\n",0);
printf("%d\n",1);
printf("%d\n",2);
printf("%d\n",0);
So in total, the output will be as follows.
0
1
2
0
I hope this answers your question; however, it does not provide an intuitive way of describing the generated output.
To understand the recursive flow you can instrument your code with few printfs like below. This will show the sequence of flow of function using indentation.
#include <stdio.h>
void printSpace(int num)
{
while(num > 0)
{
printf(" ");
num--;
}
}
int NumSpace = 0;
void fun(int n)
{
printSpace(NumSpace);
printf("fun(%d)\n", n);
NumSpace += 4;
if(n>0)
{
fun(--n);
printSpace(NumSpace);
printf("%d\n",n);
fun(--n);
}
NumSpace -= 4;
}
int main(void) {
int a;
a=3;
fun(a);
return 0;
}
Result:
fun(3)
fun(2)
fun(1)
fun(0)
0
fun(-1)
1
fun(0)
2
fun(1)
fun(0)
0
fun(-1)
Hope this helps.
i'm new to postscript. What is a format for a function that calls itself recursively. lets say I have a function called squares that prints out a square.
5 square // prints out 5 squares
I think 5 will be a the top of the stack. Each repititon will decrease that number until 0 is met. If there is an easier way to do this, let me know.
%!PS-
%
% int myfunction -
% Executes recursively 'int' times
%
/myfunction {
dup == % Print out the current 'int' just to show we're doing something
1 sub % decrement 'int' by 1
dup 0 gt % copy 'int' and test to see if its 0
{ % not 0, so recurse, the copy on the stack is the new 'int'
myfunction % execute recursion
} {
pop % The copy of 'int' was 0,so remove the copy from the stack
} ifelse
} bind def
5 myfunction
Or you could just use loop to execute a code block 5 times.
/go
{
/cnt { 1 add dup == } def
0
{ cnt } loop
} def
% start by calling go
go
a simple infinite counter that should you get started