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.
Related
I am very confused about callback function. Specifically I am confused about the order of the functions being called in the sequence of functions that make use of callback functions.
For example, I have this piece of code and problem in a question that I recently done, and the solution is below:
The procedure nthPrime shown below computes the nth prime number asynchronously; i.e., it returns
immediately and then calls callback sometime later with the value of the requested prime number. Give
code below that uses this procedure to print the product of the 100th and 200th prime numbers without spinwaiting
or polling (i.e., your code must call this procedure twice and multiply the results). You can use global
variables in your solution if you like.
void nthPrime(int n, void (*callback)(int));
So the solution is:
int t;
void nthPrime(int n, void (*callback)(int));
void foo(int n) {
nthPrime(100, a);
}
void a(int p) {
t = p; // why assign p to t here?
nthPrime(200, b);
}
void b(int p) {
printf("%d\n", t * p); // t*p, but what is p here?
}
However I am totally confused about how the solution (or functions above is being used to implement the request to print the product of the 2 primes).
I guess foo() is being called first. Then I am kind of lost how the sequences is being called (I know some functions return right-away and wait for the result of the "call-back" function to finish???). I am confused what is being returned right away, and what will be run in a near future to return something later in the sequences.
When you call nthPrime(100, a);, nthPrime will calculate the 100th prime, and then call the a function.
When it calls a, p will be that 100th prime.
a then calls nthPrime(200, b);. nthPrime will calculate the 200th prime, then call the b function.
When it calls b, its local variable p will be that 200th prime.
b needs to multiply the prime that it received by the 100th prime that was received by a. It's not possible to access variables in another function's scope directly. That's why a copies its parameter to the global variable t -- this provides the communication between the two callback functions.
In many other languages this would be done with closures rather than global variables, but C doesn't have closures. This limits the flexibility and capability of callbacks 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.
I came across the following in writing a recursive function:
#include <stdio.h>
void bin_r(unsigned int n)
{
static int s;
s++;
printf("%d", s);
if (n>1)
{
bin_r(n>>1);
}
printf("%d", s);
// ...
}
int main(void) {bin_r(1777);}
12345678910111111111111111111111111
It seems like the 'static'-ness of the variable s works as (I) expected before the recursive function call, but after it it seems to reinitialize it every time. What would be an explanation of what's going on here?
Here's an example of the code if you want to run it: https://onlinegdb.com/znV72a6Gw
You call bin_r again, before the second printf. Meaning, only when the condition (n>1) is true, will the recursion be terminated and the stack can unwind, executing the second printf [however many levels of recursion you have] times without increasing s further.
In your example, you have 11 levels of recursion, which is why you get 11 times "11" printed after the termination condition is met.
The question asks:
It seems like the 'static'-ness of the variable s works as (I)
expected before the recursive function call, but after it it seems to
reinitialize it every time. What would be an explanation of what's
going on here?
As I remarked in comments, I see no evidence of reinitialization. As a static variable declared without an initializer, s is automatically initialized to 0 at the start of the program. At each step down the recursion series, s (of which there is only one, not one per call) is incremented and then printed. The input 1777 is between 210 and 211, so the particular function given recurses to depth 11. That produces
1234567891011
on the way down. On the way back up, s, whose value is then 11, is printed again at each level without further modification, for an additional
1111111111111111111111
In comments you additionally inquired:
And is there a way to keep the static value as it would be before the recursive call (going from 1 to 11) via a static var, or I'd need to use something else for that?
The whole point of a static local variable is that it represents a single object accessed by all executions of the function. That object's lifetime is the same as the whole program's, and, like any object, it retains its last-stored value until a new one is stored or its lifetime ends. So no, there is no way to make it automatically reset after the topmost call of your recursion terminates. Moreover, being declared inside a function, it has no linkage, so it cannot be directly modified from outside the function.
Generally speaking, variables with static storage duration do not play well with recursion. They are incompatible with recursive functions that access them being used in multi-threaded programs, and those declared at block scope, such as your s, are difficult to reset from outside the block in which they are declared.
It would be possible to structure your bin_r() to address the latter issue, maybe like so:
void bin_r(unsigned int n, _Bool top) {
static int s;
s = top ? 1 : (s + 1);
printf("%d", s);
if (n>1) {
bin_r(n>>1, 0);
}
printf("%d", s);
}
Of course, that requires the caller of the top-level execution to pass 1 to signal the function to reset the variable. If you don't like that then you could change that version of bin_r to a helper function, and provide a separate, non-recursive function to perform the top-level call correctly.
But if you're going to do that, then why not just get rid of the static variable while you're at it, maybe something like this:
void bin_r(unsigned int n, int *s) {
(*s)++;
printf("%d", *s);
if (n>1) {
bin_r(n>>1, s);
}
printf("%d", *s);
}
Again, provide a one-arg wrapper for that if you like. Now you're thread-safe, and you have full control.
The other answers/comments are correct here, but here is a basic example to show two different ways that static variables may be used in a basic recursive function: before and after the self-function call:
static int digits -- used/incremented before the recursive function call.
static int sep -- used/incremented after the recursive function call.
void bin_r(unsigned int n)
{
// how many total digits -- this will be finished before unwinding the stack
// here we will increment digits BEFORE the function call, so when the stack
// is unwound we have the full length / number of digits
static int digits, sep;
if (digits==0) printf("%d --> ", n);
digits++;
if (n>1)
bin_r(n>>1, level);
putchar((n&1)==0? '0' : '1'); // == has higher precedence than &
// unwinding the stack -- separate every four digits from RTL, newline at end
// here we will increment sep AFTER the function call, so now that we unwind
// the stack, it will essentially be counting how many frames have been unwound.
sep ++;
if (!((digits-sep)%4) && digits != sep) putchar(' ');
if (digits==sep) {
putchar('\n');
digits = sep = 0; // reset statics
}
}
And here we use both methods to get our output:
1777 --> 110 1111 0001
which is combined together in this line to separate the binary digits every four from right-to-left:
if (!((digits-sep)%4) ...
I am having difficulty finding how recursion works. Some text books
says that "Recursion is when a function calls itself again and again
until some base condition is satisfied".
Some books says that "Recursion is when a function calls another
function again and again till some base condition is satisfied".
Which is true? If both are true, can we consider below given example
as a Recursion? If NO, then which is better in terms of performance,
below code or recursion?
def Function1()
{
/* do something */
}
def Function2()
{
for(i=0; i<=10; i++)
{
call Function1()
}
}
As it is, the code shows iterative calls to Function1(), if within the body of Function1() there is a call to Function2(), then it would be an indirect recursion - a function calling second function, which then calls the first again.
In general, a recursive function calls itself, either directly or indirectly. In direct recursion function, foo(), makes another call to itself. In indirect recursion, function foo() makes a call to function moo(), which in turn calls function foo(), until the base case is reached. (and then, the final result is accumulated in the exact reverse order of the initial recursive function call.)
Now, to answer your question:
Can this code be called Recursion. If not, which is more advanatgeous, given below code or recursion?
No. Iteration lacks multiple activation records (or stack frames), which makes it a better alternative.
Recursion should be used according to requirement and when you know the base condition and don't know how many times your loop should be called.
Recursion can be of different types like there can be normal recursion, infinite recursion, indirect recursion etc.
A normal recursion means calling the same function itself until a base condition is satisfied
An infinite recursion is where there will not be any base condition.
An indirect recursion is like when a calls b and b calls c and c calls back a then 'a' is being called indirectly.
Example of basic recursion:
foo()
{
base_condition;
return;
foo();
}
main()
{
foo();
}
Your example base condition can be variable equals runs for 10 times.
fun(int x)
{
if(x == 0)
return;
fun(--x);
}
main
{
fun(10);
}
Please look into the below URL for performance criteria.
performance between looping and recursion
Recursion is when
The control flow passes from a function into the very same function (directly or indirectly) repeatedly without returning first.
In your example, Function1is repeatedly called from Function2, but does return from each call before being called again, so it's not recursively called.
Let me put the pieces together: The code you provided could be recursive or it couldn't. This depends on the fact whether Function1 calls Function2. If this is the case, then you would have a mutual exclusion recursion, as pointed out by EOF.
However, this is a case that does not occur as often as normal recursion (except in pure functional environments). A normal recursion simply consists of a function which calls itself (insteaf of another function).
For further explanations and an introduction how, e. g., the recursive factorial works, see here.
Recursion occurs when a thing is defined in terms of itself or of its
type. Recursion is used in a variety of disciplines ranging from
linguistics to logic. The most common application of recursion is in
mathematics and computer science, where a function being defined is
applied within its own definition. While this apparently defines an
infinite number of instances (function values), it is often done in
such a way that no loop or infinite chain of references can occur.
Source.
So, if you have a foo and in order to calculate or execute foo, you need to recur to foo at least once more, then you have a recursion. Example:
n! = 1 * 2 * 3 * ... * n
This is an iterative definition:
int fact(n) {
int ret = 1;
int i = 1;
while (++i < n) ret *= i;
return ret;
}
This is a recursive definition:
int fact(n) {
return (n == 1) ? 1 : (n * fact(n - 1));
}
Since your code calculates Function2 with multiple usages of Function1, it is not recursive, since you did not need to call Function2 in order to evaluate Function2, nor did you need to call Function1 in order to evaluate Function1. Recursion occurs when something is its own dependency, while your code has a function which depends on another function. Your question about performance is next to impossible to answer, since there are infinite ways to implement a thing with or without recursion, when you compare a recursive approach with a non-recursive approach, then you need to have concrete implementations, or at least very strict ideas of how the two cases would be implemented. However, in general it is a good idea to prefer non-recursive approaches, as recursive approaches often have problems with the stack part of the memory, including stack overflow or infinite function calls and crashes due to bugs.
Recursion is when a function calls itself, either directly or indirectly.
Normally in the C-like languages we use recursion only when the data is tree-like. For example, you have a tree consisting of nodes, with a "next" member to indicate siblings and a "child" member to indicate children (maybe it's an XML file, or a directory tree). You want the the number of nodes so
int getNodes(Node root)
{
int answer = 1;
for(sib = root.next; sib != null; sib = sib.next)
{
answer += 1;
if(sib.child != null)
answer += getNnodes(sib.child);
}
if(node.child != null)
answer += getNodes(node.child);
return answer;
}
You can make the code a bit neater but less efficient by return 0 if root == null.
However you can use recursion for iteration. Think of it as delivering letters to a street. You can go down the street removing letters from your sack (iteration). Or you can deliver letters to the first house in the street, declare the street to be one house shorter, and repeat until the street disappears (recursion). The latter seems eccentric, but it has some advantages for automatic checking of algorithm correctness. If you forget to increment it you can't get stuck in an infinite loop, for example.
Why does it give an error of segmentation fault(core dumped) and gives no output in 1st case ?Can anyone explain how program is program callls main recursively with parameters?
#include <stdio.h>
int main()
{
static int i = 2;
if (i<7)
{
main();
printf("%d ", i);
i++;
//main(10);
}
}
-
#include <stdio.h>
int main()
{
static int i = 5;
if (--i)
{
//main();
printf("%d ", i);
main(10);
}
}
You are calling main() first and then incrementing i
if (i<7)
{
main(); // <-- main called when i still 2
printf("%d ", i);
i++; // <-- statement never reached
//main(10);
}
Hence, while main() calls main() recursively, the statement i++ is never reached.
You should increment i before calling main()
if (i<7)
{
i++;
main();
printf("%d ", i);
//main(10);
}
1st case the i++ after the call of main(), that means the program has no chance to add the i, and into infinity loop, and stackoverflow! haha....
but the 2nd case, it's reduce the i before you call the main.
TL;DR StackOverflow (Pun or no pun, it's true both ways).
First: Some important information
This case has nothing to do with passing an argument to main() or not. Actually, as per the latest C standard, C11, for a hosted environment, the conforming signature of main() is int main(void) and following that, main(10); is wrong, altogether.
Now, coming to the actual problem here,
In the first case, change of i value happens after the call to main(), so in effect, the value of i never get changed because the control never reaches the statement which modifies i. Hence, it's an infinite loop, and because of the recursive call to main(), stack overflow happens.
In later case, i value gets updated before call to main(), so that value actually reflects. Thus, at some point (after 4 occurrences, actually), the if condition meets a FALSE condition and the recursive call ends and the stack unwinds.
First case:
i++ is positionned after the call to main. So i will always be equal to 2, as you never reach this part of the code. You are then calling your main function everytime, leading to an infinite recursion, and thus to the segmentation fault. The fix for this case would be to increase i before calling the main function.
if (i<7)
{
i++; // Increment before calling the main function, so i value is changed
main();
printf("%d ", i);
}
Do note that it will lead to something which looks like your second case, except that you will print several "7".
Seconde case:
In the second case, you are decreasing the value of i everytime you enter your if condition. When you finally can't enter your if condition anymore, it means i is equal to 0 (as if(0) is equivalent to if(false)). Everytime you will return to the previous called main function, i will still be equal to 0, explaining why you are displaying "0" everytime. If you want to print the different values, you can place your printf before the call to the main function for instance.
In the first case:
"i" is never incremented therefore you run in an infinite loop and get an overflow.
In the second case:
You call the recursion before displaying the value of "i", after four calls "i" equals to 0 and your recursion stack unwinds.
Modify your condition and perform outputs before the recursion call.
In the first case, i is never incremented, hence, the main keeps getting called and soon enough there is no more stack memory available to the program.
In the second case, the last updated value of i is intact throughout the lifetime of i. As i is static, program is referring to the same memory address on all the iterations. While printing i you see the last updated value, that is 0, as output.