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) ...
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.
Update: Hi, I did not misunderstood the goal of the function. I was just surprised that static int sum = 0 does not execute each time the function is called, so I don't understand that. The goal of the function is correct: to sum the values and give the final value, and it works fine. The question is: Why isn't the sum changing into 0 each time the function is called? I suppose that's how it is set up by convention? That since I put static int sum, it will run only once and make it equal to zero, but then it won't run this line of the code again when the function is called?
In the following code, the only way I could make this function work was when I declared that sum = 0.
I was expecting the output to be 55, 45, 50, since sum is getting value 0 each time it is run! But for some reason, after the second time the function is called, the first line "static int sum = 0;" is skipped. Why? Thanks a lot =)
#include <stdio.h>
int sum (int num)
{
static int sum = 0;
sum = sum + num;
return sum;
}
int main()
{
printf("%d ",sum(55));
printf("%d ",sum(45));
printf("%d ",sum(50));
return 0;
}
Since sum (variable) is getting value 0 each time it (sum function) is run!
No, it's not.
But for some reason, after the second time the function is called, the first line static int sum = 0; is skipped. Why?
It is not skipped. That is just your impression. But the initialization of 0 happens only once prior to program startup.
If the function is called everytime there's a call to sum(), why doesn't sum (variable) gets the value of 0, since it is written in the beginning of the function?
Because sum is qualified with the static storage class specifier, which means that the sum variable is not destroyed after the function has been executed once and it retains its value for the whole entire program execution.
An object whose identifier is declared without the storage-class specifier_Thread_local, and either with external or internal linkage or with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
Source: ISO/IEC 9899:2018 (C18), ยง6.2.4/3
Omit static at the sum variable and you get your desired result.
Note that the purpose of the sum function is pretty useless in that way. I guess it is just for testing purpose only.
EDIT:
For me it seems that you actually got the function from somewhere else and misunderstood the purpose of the program and the function sum.
The original purpose of the function sum is to sum the input values provided at different function calls to sum() and return the current sum at each function call.
That is the reason, why sum (variable) is qualified with static (to retain its value).
The purpose is not to just pass the input value through, which is what think the purpose of sum() is.
I was writing the c language code for selection sort. It was working fine If the swapping was done with using Third Variable but when I changed the method of swapping without using third variable as shown in the code comment below. It is showing wrong Output( zeros at some positions).I cannot figure out why this is happening?
I have tried to swap two numbers without third variable in another program for the same type of conditions. But it is working fine there. But Why not in my selection sort program.
#include<stdio.h>
void selectsort(int * ,int);//selection sort function
int main(){
int a[5];
int i,n=5;
for(i=0;i<5;i++)
scanf("%d",&a[i]);
selectsort(a,n);
printf("Sorted Array is:\n");
for(i=0;i<5;i++)
printf("%d\n",a[i]);
}
/* Below is selection sort function definition*/
void selectsort(int*p ,int q){
int i,j,h,temp;
for(i=0;i<q-1;i++){
h=i;
for(j=i+1;j<q;j++){
if(p[h]>p[j]){
h=j;
}
}
/* below code is to swap the two numbers ( p[i] and p[h]) without
using third variable , but it is NOT WORKING here
(giving wrong output) BUT WORKING IF THIRD VARIABLE IS USED.Why?*/
p[i]=p[i]+p[h];
p[h]=p[i]-p[h];
p[i]=p[i]-p[h];
}
}
Your values of h and i are not quaranteed to be different.
Swapping in this case will not only not swap anything but also mess up your memory.
void selectsort(int*p ,int q){
int i,j,h,temp;
for(i=0;i<q-1;i++){
h=i; // <=== Here you start with identical values
for(j=i+1;j<q;j++){
if(p[h]>p[j]){
h=j; // This may or may not be executed.
}
}
// Here h can still be at same value as i.
// What happens in this case is shown in the comments below:
p[i]=p[i]+p[h]; // p[i]=p[i]+p[i]; ==> p[i] *=2;
p[h]=p[i]-p[h]; // p[i]=p[i]-p[i]; ==> p[i] = 0;
p[i]=p[i]-p[h]; // p[i]=p[i]-p[h]; ==> p[i] = 0;
}
}
You could add something like this before doing the swapping:
if (i==h)
continue;
Note:
Apart from academic cases I would not suggest using such an approach.
Swapping without a temporary variable has lots of downsides:
Only works for integer types
Needs handling for overflow etc.
Needs handling for identical storage locations.
Needs extra arithmetic operations causing more code and longer execution time
Is confusing readers and harder to maintain
It also only has one advantage
Saves stack storage for 1 variable.
If your goal is to confuse readers, then you should search for a version using XOR instead of arithmetics. ;)
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.
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.