How does this Decimal to Binary conversion program work? - c

I was looking for an easy program for the decimal to binary conversion and then, came across the following program using recursion.
void bin(unsigned n)
{
/* step 1 */
if (n > 1)
bin(n/2);
/* step 2 */
printf("%d", n % 2);
}
int main(void)
{
bin(4);
return 0;
}
The output of this program was 100 as expected. But, I'm unable to understand how does it show the output 100 because according to me, the output should be 1 (incorrect) instead of 100.
Here is my interpretation of steps of the bin function.
We will put 4 as an argument of bin first.
4 > 1, therefore, it will again call the bin function with the argument 2.
Now, 2 > 1, therefore, it will again call the bin function with the argument 1.
Since 1 is not greater than 1, we will go to step 2 and the compiler will print 1 (since 1%2=1) and hence, this program should print 1 only and not 100.
Can anyone please explain and guide me where I am wrong?

Perhaps the illustrated sequence will make it easier for you to understand:
bin(4)
bin(2)
bin(1)
printf("%d",1%2); // 1
printf("%d",2%2); // 0
printf("%d",4%2); // 0

You are on the right track,
We will put 4 as an argument of bin first.
bin(4): 4 > 1, therefore, it will again call the bin function with the argument 2. Function execution is not complete yet. Program will return here once the called function is executed
bin(2): Now, 2 > 1, therefore, it will again call the bin function with the argument 1. Function execution is not complete yet. Program will return here once the called function is executed
bin(1): Since 1 is not greater than 1, we will go to step 2 and the compiler will print 1 (since 1%2=1) and hence, this program should print "1". Fcuntion execution complete
bin(2): program now returns to the caller function and prints 0(since 2%2=0). function execution complete
bin(4): program now returns to the caller function and prints 0(since 2%2=0). function execution complete
Hence the ouput is '100'

Dividing an integer by 2 is the same as shifting it right one bit. So using recursion, it shifts the bits to the right until only 1 bit is left (the leftmost bit)
Then it prints this leftmost bit and returns. Upon return, there are still two bits, the leftmost and one-before-leftmost. With the % 2 it discards all leftmost bits and prints this one-before-leftmost. Now it returns and... etc.
This effectively prints the bits left-to-right.

With your logic:
somefunc();
someotherfunc();
When somefunc() is finished doing it's thing, someotherfunc() will not be executed since somefunc() was done.
What happens is that step 2 is done when the call to bin is done or not run at all and then step 2 is always done. Thus Every iteration of bin prints something and since it's after the recursion it does it from the deepest and and up making the printing in reverse order from the actual recursive path.
Every call to binhas it's own local variables so they don't interfere with each other. Thus when the call to bin from bin is done n is the same as before but the returning bin had a n that was half of the caller's n.

Related

Stacks and Recursion in C

#include <stdio.h>
void fun(int a) {
if (a > 0) {
fun(a / 10);
printf("%d", a % 10);
fun(a / 10);
}
}
int main() {
fun(12345);
return 0;
}
Here, as the function is calling itself at the start of the if block, shouldn't it print nothing, it will keep calling itself until the function argument becomes zero?
But instead, the output is 1213121412131215121312141213121
shouldn't it print nothing, it will keep calling itself until the
function argument becomes zero?
If I have understood correctly then you are right. The function will not output anything until a is equal to 0.
void fun(int a){
if(a > 0){
fun(a/10); // calls itself.
printf("%d",a % 10);
//...
Thus for this number 12345 the first output will be the most significant digit 1.
As the function calls itself twice
void fun(int a){
if(a > 0){
fun(a/10);
printf("%d",a % 10);
fun(a/10);
}
}
then for each digit of the number except the most significant digit the previous and next digits will be outputted twice on the left and on the right sides. For example
1 2 1
1 2 1 3 1 2 1
1 2 1 3 1 2 1 4 1 2 1 3 1 2 1
and so on.
I used embedded spaces for make the output more clear.
After the inner most function of the recursion has been finished (a>0) is evaluating to false it will execute the print statement and returns to the calling function.
The caller will print it's a%10 value and so on.
Not sure why you call fun(a/10) twice but this is why the output is printed twice.
Yuo do not need the second call
void fun(int a)
{
if(a)
{
fun(a/10);
printf("%d", a % 10);
}
}
https://godbolt.org/z/zWf64jjWe
Remember that it will not work for negative numbers.
The function attempts to print the decimal conversion of a but the second recursive call produces extra output.
The function will indeed produce no output for values below 10, which might not be the expected behavior. Without the second recursive call the output would be 1234.
You should use this instead:
void fun(int a) {
if (a >= 10)
fun(a / 10);
printf("%d", a % 10);
}
Note however that the above function only works for positive values.
You can implement this is 3 different ways:
Either make the recursive call before you start printing. If so the printing starts from the deepest level of recursion. This is very inefficient but ensures that you get the expected order 1,2,3... Generally, a recursive function that doesn't have the recursive call at the very end is an incorrect solution to any problem.
Or make the recursive calls after you print. This would lead to everything getting printed backwards as you've currently written the function. However, a recursive function with the call at the end, so-called "tail call", can sometimes get optimized into nearly as efficient code as a loop. You could probably do this here too, if you come up with a different algorithm.
Or you can implement it as a loop. Super-fast, super-readable, no risk of excessive stacking, no overhead. This is the correct solution in some 99% of all cases and the correct solution in 100% of all cases a beginner might be facing.

could someone tell me what is wrong with this?

Question: wow, you are given two things:
The calling order in which all the processes are called.
The ideal order in which all the processes should have been executed.
Now, let us demonstrate this by an example. Let's say that there are 3 processes, the calling order of the processes is: 3 - 2 - 1. The ideal order is: 1 - 3 - 2, i.e., process number 3 will only be executed after process number 1 has been completed; process number 2 will only be executed after process number 3 has been executed.
Iteration #1:
Since the ideal order has process #1 to be executed firstly, the calling ordered is changed, i.e., the first element has to be pushed to the last place. Changing the position of the element takes 1 unit of time. The new calling order is: 2 - 1 - 3. Time taken in step #1: 1.
Iteration #2: Since the ideal order has process #1 to be executed firstly, the calling ordered has to be changed again, i.e., the first element has to be pushed to the last place. The new calling order is: 1 - 3 - 2. Time taken in step #2: 1.
Iteration #3: Since the first element of the calling order is same as the ideal order, that process will be executed. And it will be thus popped out. Time taken in step #3: 1.
Iteration #4: Since the new first element of the calling order is same as the ideal order, that process will be executed. Time taken in step #4: 1.
Iteration #5: Since the last element of the calling order is same as the ideal order, that process will be executed. Time taken in step #5: 1.
Total time taken: 5 units.
S: Executing a process takes 1 unit of time. Changing the position takes 1 unit of time.
Input format:
The first line a number N, denoting the number of processes. The second line contains the calling order of the processes. The third line contains the ideal order of the processes.
Output format:
Print the total time taken for the entire queue of processes to be executed.
Constraints: 1<=N<=100
SAMPLE INPUT
3
3 2 1
1 3 2
SAMPLE OUTPUT
5
The first method that came to me was to declare a variable and increase it by one after every swap plus 2, but then if we take an array of size 3, there are only two possibilities. Hence I printed those out, and yes guys this is a problem from an online judge, there was no syntax error, but in the site it tells that there was some problem in declaration, I have no clue what to do I am new to programming and can someone suggest a new method which is applicable for arrays of bigger sizes.
#include <stdio.h>
swap(a,b);
long long int a,b;
int main(void) {
long long int n,i;
long long int a[3],b[3];
scanf("%d",&n);
for(i=0;i<=2;i++)
{
scanf("%d",a[i]);
}
for(i=0;i<=2;i++)
{
scanf("%d",&b[i]);
}
if(a[i]=b[i])
{
printf("2");
}
while(a[i]!=b[i])
{
swap(b[0],b[2]);
swap(b[0],b[1]);
{
if(a[i]=b[i])
printf("5");
}
}
return 0;
}
swap(a,b){
long long int temp;
a=temp;
b=a;
temp=b;
return swap(a,b);
}
Your swap() function has multiple issues:
1: It calls itself with return swap(a,b); in the last line of the function. This will result in infinite recursion and a stack overflow.
2: You need to declare the return type of the function. If it takes two long long parameters and returns nothing, then it should be declared as follows:
void swap(long long a, long long b);
3: As written, the function will have no effect anyway. You need to pass pointers to these variables if you want to change their values:
long long swap(long long *a, long long *b);
4: To pass pointers to this function, prefix the parameters with & as follows:
swap(&b[0],&b[2]); /* NOT: swap(b[0],b[2]); */
5: The order of operations in the swap() function is also wrong. You start by irretrievably losing the value of a instead of storing it so that it can be assigned to b. Try this instead:
void swap(long long *a, long long *b) {
long long temp;
temp = *a;
*a = *b;
*b = temp;
}
NOTE: Please learn how to format your code properly. Also, always compile your development code with warnings enabled (e.g., add -Wall -pedantic to the command line). Doing so would have drawn your attention to most if not all of these problems without having to ask here.

Understanding recursion function call

Where will the value of n be stored after first call to factorial()?
When n=1 then return 1 is sent, why doesn't res becomes equal to 1 in main function?
#include<stdio.h>
int factorial(int n)
{
if(n<=1)
return 1;
else
return n*factorial(n-1);
}
int main()
{
int res =factorial(3);
printf("%d",res) ;
}
The run-time stack will have four functions in total: main(), factorial(3), factorial(2), and factorial(1). Each of these gets its own variable space. There are three instances of the variable n, one for each call to factorial.
When factorial(1) returns 1, that value isn't returned to main(), because main() is not what called it: factorial(2) called it. That instance performs the operation 2*1 and returns 2. The caller of that instance is factorial(3), which receives the 2, performs the operation 3*2, and returns a value of 6 to its caller, main().
Does that help clear it up? If not, I have two suggestions:
(1) Search this topic on StackOverflow and the internet in general; there are plenty of detailed walk-through examples of factorial.
(2) Insert print statements to trace the flow of data and execution. Within factorial, separate the computation and the return, so you can put a print in between:
catch = factorial(n-1)
result = n * catch
print n, catch, result
return result
Each time a function is called, its parameter and local variables are pushed onto the stack. In the case of a recursive function, there will be a set of the variables on the stack for each active invocation of the function.
In this example, the first call to factorial has n set to 3. Within the function, factorial is called again, this time with n set to 2. It calls itself one more time with n set to 1. In this last call, it returns a value of 1. This gets returned to the prior invocation where n is 2, which then returns 2 * 1 which is 2. This value is returned to the first invocation where n is 3 and returns 3*2 which is 6 back to main.
So the call stack looks like this:
main
|--> factorial(n==3)
|--> factorial(n==2)
|--> factorial(n==1)
return 1
return 2*1
return 3*2
print 6
n is not stored in the way of global or static variables - it's stored on the stack. Calling a function with arguments the arguments are being pushed on the stack.
See what's happening when your running your program:
factorial(3) gets called (in main)
As n is not equal or smaller to 1 factorial(2) is called and the result will be multiplied by n (is 3).
As n is not equal or smaller to 1 factorial(1) is called and the result will be multiplied by n (is 2).
As n is now equal or smaller to 1 the function returns 1
factorial(2) returns 1*2
factorial(3) returns 2*3
res will be 6

difficulty in understanding successive recursive calls

I am trying to understand the following program in which successive recursion function calls are present, but getting confused while tracing how the tack gets loaded.
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[]){
if(a[1]=='\0')
return;
func(a+1);
func(a+1);
printf("%c",a[1]);
}
the output for this is 3 3 2
would appreciate if someone could advise on this one...
does this kind of multiple recursive calls beneficial in any way or find application in specific problem areas..?
Just put yourself in the position of the CPU and step through line-by-line (or use a debugger to help with that task).
The first call is to
func("123")
this call does not satisfy the termination condition a[1] == '\0', so it calls
func("23");
The call to func("23") in turn calls
func("3")
which DOES satisfy the return condition. So, that call returns to the previous caller, func("23").
func("23") proceeds to make another call to func("3") due to the lines
func(a+1);
func(a+1);
Continue this process of executing the program in your mind, and write down what would be in each call to printf. That will explain your output.
UPDATE
Note that the call to printf() happens after the recursive calls, so e.g. a call to
func("123")
would proceed like
Enter func("123")
Termination condition not met
Call func("23")
Call func("23") again
Printf("3") (which is a[1])
Return
Debugging with breakpoints is one way to understand recursion. Another way is to draw the tree of recursive calls.
From the figure, In every level after level0, the printf statement occurs after every two nodes owing to these two lines of code:
func(a+1);
func(a+1);
In general, this becomes a perfect binary tree for any input string of length greater than 0. The total number of nodes is given by this formula:
2^(k+1) - 1 // k is the depth; here k = 2
Total number of printf statements executed can be obtained by this formula:
2^k - 1 // For k=2, there will be 3 printf statements each printing 3,3,2 respectively
the posted code is a rather poorly designed instance of recursion.
The following code has the correct 'tail' form of recursion.
It could be made even better by passing the reversed string back to main and let main print it.
It reverses the order of the string passed to func() by main()
Please, when asking about a runtime problem, post code the compiles, including the necessary #includes for header files so we are not guessing about which headers to include
#include <stdio.h>
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[])
{
if(a[1]=='\0') // check for end of recursive sequence
{
printf( "%c", a[0] ); // last tail action
return;
}
func(a+1); // step+next recursion
printf( "%c", a[0] ); // tail action
return;
}
The recursion can be simply understood as follows.
For example:
Func(int a){
while(a>1)
return a * func(a-1);
}
Suppose a = 5.
What happens is that it returns 5 * func(4).
Now func(4) returns 4 * func(3) and it goes on like this.
Check out this example for use of recursion in fibonacci series.

C Programming - Class project

http://pastebin.com/uws2Ts96 - my program so far
I'm attempting to write a C program for my class where the program will display a menu giving 3 options, option 1 will lead to the function named ExtractLargestDigit, and option 2 will lead to DigitOccurrence, and option 3 will end the program.
The problem I'm having is that i want to make it so if the user enters any value other than 1 2 or 3 the program will print out WRONG OPTION and reprint out the menu and ask for another option.
I thought the way I was going about it was correct but every time I run the program it crashes. I believe there's a problem with my while loop.
I also am having problems with the 2 functions:
For the first function I want to have the user enter in a number, for example 123456, and have the program go through each digit of the number and print out the largest digit, and at what position did it occur in the number. For example in this number (123456) the largest digit is 6 and it is in the ones digit position.
For the second function I want the user to enter in 2 numbers (123423) and (452313) and have the program break the numbers down into their digits, assign them to an array, count the number of times each digit occurs and print out a list from 1-0 with the number of times the number occur along side it.
Any thoughts on these problems would be greatly appreciated.
You must pass the address of the variable using & to scanf:
scanf("%d", &option);
That's why it crashes when you run it.
You're using the assignment operator (=) as opposed to the comparison operator (==) in four of your while conditions:
while(option = 0) should be while(option == 0)
You also shouldn't have a ; straight after the condition, otherwise if the condition is true it'll always be true and you'll have an infinite loop.
while(option == 0); { ... } should be while(option == 0) { ... }
Otherwise the body of the loops aren't actually the body of the loops, they're completely unrelated to the loop.
Also, scanf("%d", option); will treat the value of option (0) as an address and try to store the inputted integer into the wrong spot of memory, causing undefined behaviour (most likely a crash). If it doesn't crash, option will remain as 0.
You should also check the return value of scanf to ensure that the right amount of items were inputted. That may also involve getting rid of any junk input up until the next newline (or EOF).
I also don't understand why you have all of those while loops. If you're trying to create a menu that loops, have one single loop where the termination condition is the option that indicates exit (in your case it looks like that's 3). You could have a switch statement inside that single loop to call the right function based on the value of option.
And a return; isn't necessary at the end of a void function.
EDIT: About those two functions, the common way of splitting a number into it's digits is:
WHILE num IS NOT 0:
digit = num MOD base
num = num DIV base
Since decimal is base 10, you'd compute the modulus (% in C) and division of num with 10. If you wanted binary digits, you'd use a base of 2. Then just do whatever you need to with each digit at every iteration. The digits will obviously be extracted starting from the end (least significant digit).
Lastly, turn up the warnings on your compiler so it'll tell you about the problems above, ie:
gcc -Wall -o test test.c
test.c: In function ‘displayProgramMenu’:
test.c:44:2: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat]
test.c:46:2: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
test.c:48:2: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
test.c:49:2: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
test.c:50:2: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
And (lastly + 1) you can get rid of conio.h and replace getch() with getchar() or getc(stdin).

Resources