I took a C Advanced Course on Udemy, and there is a question from there:
What will be the output of the following code?
#include <stdio.h>
int main(void){
static int i=5;
if(--i){
main();
printf("%d ", i);
}
}
The right answer is 4 3 2 1, but when I run this code in my IDE (and online compilers), it prints 0 0 0 0.
In the course lector uses cygwin compiler and I have g++. May it be the reason of the inconsistency?
Also I'm wondering if if(--i) method is faster then for loop by the concept of performance?
Thank you.
The reason is main() is called before printf("%d ", i). So when if block is executed, main() function is called before printing the value of i and it's continue to do so until if-condition is false. Here if-condition became false when i is equal to 0. When the if-contidion is false the function return to the previous state from where it have been called and then print the value of i, which is now 0.
To print 4 3 2 1, print the values before calling main() funtion like bellow
int main(void){
static int i=5;
if(--i){
printf("%d ", i);
main();
}
}
The posted code shall print 0 0 0 0 because the printf is after the recursive call, i.e.
main(); // Recursive call
printf("%d ", i); // Print after
If you instead do:
printf("%d ", i); // Print before
main(); // Recursive call
the output will be 4 3 2 1
So I think your lector used the last form and you used the first form, i.e. different code, different results
Related
Newb here.
I'm probably missing something trivial but:
Here's the thing: http://i.imgur.com/8BmPci5.png
#include <stdio.h>
#include <stdlib.h>
int main()
{
//Sort Numbers (zuerst)
int numbers [10];
int i,j;
j = 0;
int read;
printf("Input numbers: \n");
for (i=0;i<10;i++) {
scanf("%d",&read);
if (read == 27) {
break;
} else {
numbers[i] = read;
j++;
}
}
printf("j is: %d, i is: %d\n", j, i);
for (i=0;i<j;i++) {
printf("numbers[%d] is: %d\n", i, numbers[i]);
}
return 0;
}
Output:
Input numbers:
1
2
3
^[
j is: 10, i is: 10
numbers[0] is: 1
numbers[1] is: 2
numbers[2] is: 3
numbers[3] is: 3
numbers[4] is: 3
numbers[5] is: 3
numbers[6] is: 3
numbers[7] is: 3
numbers[8] is: 3
numbers[9] is: 3
I have a for loop (goes from 0 to <10). I also have a scanf inside wich scans for an int. If it ain't ESC (ASCII 27), then it puts it into an array and it increments the value of j. If it's an ESC, it ('s supposed to) break (exit the loop). Later, only j (or j-1) number of array items would be printed.
Issue: j (and i too) increments to 10, even if break is called at ~ i = 3 or 4.
Break supposed to exit the for loop without doing anything after it's called, right? Quote from BeginnersBook.com:
It is used to come out of the loop instantly. When a break statement is encountered inside a loop, the control directly comes out of loop and the loop gets terminated. It is used with if statement, whenever used inside loop.
What's wrong with my code? Thanks in advance.
You're being naughty in that you're not checking the return value of scanf, which will tell you the number of variables that were successfully populated. In your case, you want that to be 1 to signal that something was read into your variable read.
If you try to pass \033 (ASCII encoded ESC), then scanf will fail to parse that to an int. Then the previous value of read will be retained (which could give you undefined effects if it hasn't yet been set to anything), and read == 27 will almost certainly be 0. That behaviour accounts for the output you are observing.
If scanf does fail, you could try reading a char from the stream, and check if that is equal to \033.
void count(int n)
{
static int d=1;
printf("%d", n);
printf("%d", d);
d++;
if(n>1)
count(n-1);
printf("%d", d);
}
void main()
{
count(3);
}
Output calculated by me is 3 1 2 2 1 3 4
And Output given by book 3 1 2 2 1 3 4 4 4
I know why my answer different.
In book solution they are executing printf statement in "if" loop always. But as I study in my book scope of if, for and while loop is up to next statement if parentheses are not present.
After if statement true count is called and printf not get executed. But why they are executing it each time.
If you do not give parenthesis to your if, for, while statements they will only execute next line. After changing:
if(n>1)
count(n-1);
printf("%d", d);
To:
if(n>1){
count(n-1);
printf("%d", d);
}
Your output will become closer to what you expected it to be:
gonczor#wiktor-papu:~/tmp$ gcc main.c -o main
gonczor#wiktor-papu:~/tmp$ ./main 31221344
static d:1
count(n:3)
print(n) // 3
print(d) // 1
++d:2
count(n:2)
print(n) // 2
print(d) // 2
++d:3
count(n:1)
print(n) // 1
print(d) // 3
++d:4
print(d) // 4
print(d) // 4
print(d) // 4
The first 4 is printed because the if guard stopped the recursion. The second 4 is printed as the (recursive) function call for count(n:1) has returned. The third 4 is printed as the (recursive) function call to count(n:2) has returned.
I think your confusion is that you believe that making a recursive call causes the caller to end any further processing of its function body. But this is not the case, unless there is a return statement that ends the function early. For example, if the recursive call was guarded like this:
if (n>1) {
count(n-1);
return;
}
print("%d", d);
Then, the output would match your expectations. Only one 4 would be printed, the one that executed because the if evaluated false. All the other recursive calls would execute return after completing, so no other 4 will appear.
Also note:
if (n>1)
count(n-1);
printf("%d", d);
and
if (n>1) {
count(n-1);
}
printf("%d", d);
are equivalent. And the code means: print d after the if block completes. There are two ways for it to complete. One way is when the if condition is false. The other way is when the if condition is true, the recursive call is performed, and then that call returns. When recursive call returns, the if block completes, and then d is printed.
Further note, while very closely related, and computationally equivalent, recursion cannot be considered an ordinary "loop". A recursive call implies multiple active local stacks, while an ordinary "loop" only has the current local stack, and the loop execution block. Thus, a print statement after an ordinary "loop" will only get executed once, which is after the loop completes. However, code that follows a recursive call will get executed after the recursive call returns. So, if the recursive call is performed 2 times, there are three active local stacks that need to complete. In your code, each of those local stacks want to print d after the if block completes.
If the output by the book is '3 1 2 2 1 3 4 4 4'
#include <stdio.h>
void count(int n)
{
static int d=1;
printf("\nN IS: %d", n);
printf("\nD IS: %d", d);
d++;
if(n>1) count(n-1);
printf("\nFINAL D IS: %d", d);
}
int main()
{
count(3);
return 0;
}
if not change this:
if(n>1)
{
count(n-1);
printf("\nFINAL D IS: %d", d);
}
// Define the recursive function.
int collatz(int p1)
{
// While Loop Starting
while (p1>1)
{
//when the number is even
if(p1%2==0)
{
p1 = p1/2;
printf("%d ", p1);
//using recursion
return collatz(p1);
}
// Case where number is odd.
elseif
{
p1 = 3*p1+1;
//print function
printf("%d ", p1);
//using recursion
return collatz(p1);
}
}
}
// Main body.
int main()
{
// Declare the variable and initialized it.
int p1= 4;
//print function
printf("User Entered value : %d\n", p1);
// Display the number
printf("%d\n", collatz(p1));
//End
return 0;
}
Output: I am getting the Output as :
2 ,1, 1
I should not get the last number 1 repeated.Could you please correct me where i have done mistake.Please do the needful.
You should always enable warnings when you compile a C or C++ program. Had you done do, the compiler would have warned you that your function collatz could terminate without returning a value. (What happens if the argument is 1?)
That's undefined behaviour, and so is the use of the possibly-nonexistent return value in your main function.
So it is just a quirk of chance that it happens to print 1 in main. But whatever it printed would be wrong because you seem to expect the output to be limited to what is printed in collatz.
You might try playing computer and executing your function with a pencil and paper. It won't take very long. Of course, you could also use a debugger.
So, I have two questions.
Question 1) I find recursion difficult in C. And I have this one question, that I dont know how should I go about attempting it. I want to know its output, Please help me.
#include <stdio.h>
void fun (int);
int main (void)
{
int a;
a = 3;
fun(a);
printf("\n");
return 0;
}
void fun ( int n )
{
if ( n > 0 )
{
fun(--n);
printf("%d",n);
fun(--n);
}
}
How can I solve this recursion manually?
I know during recursion, the information is stored on stack. Therefore, I tried doing it by that way. Firstly, a will be decremented all the way upto 0. But then, it will exit out of the loop. So, when will it print the values?
Question 2) Also, I Wanted to know since the topic I am studying right now is functions. If I make a function and lets suppose it returns some value, then IS IT MANDATORY that I collect its value upon calling or I can call it without collecting its return value?
For eg: Let's say I made the function as,
int foo ( int a )
{
........
return b;
}
Now, if I call this function from inside main, then is it mandatory that I store the returned value in some variable?
You had 2 questions: the first one is what happens in your code:
To your question #1: Function fun(n) could be rewritten so that it is functionally equivalent but easier to understand, as:
void fun(n) {
if (n > 0) {
fun(n - 1);
printf("%d", n - 1);
fun(n - 2);
}
}
That is:
for fun(n)
if n > 0,
first call fun(n - 1)
then print the number n - 1
lastly call fun(n - 2)
Thus the following happens when unwinding the recursion:
fun(3) ->
fun(2) ->
fun(1) ->
fun(0) ->
n <= 0 -> exits
prints 0
fun(-1) ->
n <= 0 - exits
prints 1
fun(0) ->
n <= 0 - exits
prints 2
fun(1) ->
fun(0) ->
exits as n <= 0
prints 0
fun(-1) ->
exits as n <= 0
Execution goes from up to down sequentially - thus the output 0120 from the prints lines.
Question #2:
No, return value does not need to be stored in a variable. In fact, the printf you used returns an int, that tells the number of characters written, but you did not store that return value anywhere.
For no 1 - Get a note pad and a pencil.
Start off an write fun(3) - It is in Main.
You can now cross that out an instead write
if ( 3 > 0 )
{
fun(2);
printf("%d",2);
fun(1);
}
(applying the logic of --n)
Repeat with both of those fun. You can do the leg work on this one
Number 2 - You do not have to collect the return value from a function
I would like to answer your second question About storing the value returned by the called function.
The answer returned by the called function can be displayed in two ways..
No.1-You need not store it in any variable in the calling function and print it directly as follows:
#include<stdio.h>
#include<conio.h>
void main()
{
int a=10, b=9, add(int,int);
printf("Sum of %d and %d is : %d",a,b,add(a,b));
getch();
}
int add(int m,int n)
{
return(m+n);
}
Here,the function call has been written in the printf() function and hence the need of an extra variable has been eliminated
No.2-The other way and the code for the same-
#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
int a=10,b=9,c,add(int,int);
c=add(a,b);
printf("Sum of %d and %d is : %d",a,b,c);
getch();
}
int add(int m,int n)
{
return(m+n);
}
So,you do need a variable for the second method.Because there has to be something to catch the value thrown by the called function
I am learning recursion now-a-days. Here are three codes. The first and third is giving me the expected output but the second is not? Can somebody tell me what is just the difference in them.
Code 1:
void tail(int i){
if (i>0) {
printf("%d\n",i);
tail(i-1);
}
}
int main()
{
tail(5);
}
Code 2:
void tail(int i){
if (i>0) {
printf("%d\n",i);
tail(i--);
}
}
int main()
{
tail(5);
}
Code 3:
void tail(int i){
if (i>0) {
printf("%d\n",i);
tail(--i);
}
}
int main()
{
tail(5);
}
output of Code 1:
5
4
3
2
1
output of Code 2:
5
5
5
.
.
. Infinite
output of Code 3:
5
4
3
2
1
Please help me out. I am confused!
Result is as expected
decrement is post decrement so it would first use current value and then decrement. So function gets repeatedly called with current value so infinite loop.
Working fine for me . Similar to first
Of course code number 2 won't. In code number 2 you typed tail(i--); what -- operator (after the variable name) does is first using him in the line you requested and THEN decrease him by one.
Let's say I have the line printf("%d", i--); It'll print i in it's current value and only after printing it, it will be decreased, it first uses I, and then decreases it - same would happen if you would just type:
printf("%d", i);
i--;
About the -- operator BEFORE the variable. It'll first decrease and then do the requested action - so printf("%d", --i); will decrease i by one and then print it.
We all agree code 1 works well, code 2 actually is in an infinite loop BECAUSE you decrease the variable AFTER calling the function - so it decreases in one function only.
Basically, what it does is like:
printf("%d", i); //which is 5
tail(i);//which is still 5
i--; //will never get to this line because we called another function with variable 5
and so on.
About code number 3, it works perfectly, it's like code number 1 (but code number one won't actually decrease the variable, just call the function with the variable-1).
EDIT:
for more information, you can search in this article :)
The 3 have to work. The 2 don't work because i is decremented after been passed to the function.
You should work with pointers in second case. Each time you are passing the same value into recursive function ... first goes function call and after that you have decrement operation. As a result you have the same value (5) in each recursive call.
The second doesn't give you your desired output because you are using post-decrement operator i--.
This means "use i and then decrement i" as opposed to --i which means "decrement i and then use i".
So in your third case, i whose value is 5, gets decremented to 4, and then tail(4) is called.
In the second case, tail(i--) is called, which means call tail(5) and then do i-=1; .
If i-- and --i are given as standalone statements, they are equivalent, for example
for(int i=5;i>0;i--)
is effectively the same as
for(int i=5;i>0;--i)
But in cases such as follows:
int i=5;
int a=i--;
printf("%d %d", i, a);
This gives out put 4 5 whereas
int i=5;
int a=--i;
printf("%d %d", i, a);
will give output 4 4.