Reputation: 3616
At the moment I am coding a program in which I need a variable count
that increments every time I call the function. In my case I have a recursive function and want to know how many iterations the program does.
I simplified the code by computing the factorial of a number.
My first approach does not work and ends up with warning messages:
#include <stdio.h>
int factorial(unsigned int i, int *count)
{
*count += 1;
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1, &count);
}
int main()
{
int i = 10;
int count = 0;
printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, &count));
return 0;
}
warning: passing argument 2 of ‘factorial’ from incompatible pointer type
My second approach does not work either but also does not ends up with any warning messages.
#include <stdio.h>
int factorial(unsigned int i, int count)
{
count += 1;
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1, count);
}
int main()
{
int i = 10;
int count = 0;
printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, count));
return 0;
}
How can I make it run? Any ideas? I use Ubuntu and gcc.
Upvotes: 0
Views: 1320
Reputation: 25286
There is no need for static variables, as other solutions suggest. The following is correct:
int factorial(unsigned int i, int *count)
{
*count += 1;
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1, count);
}
int main(void)
{
int i = 10;
int count = 0;
printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, &count));
return 0;
}
One note: as the order of parameter evaluation in the printf
statement is not guaranteed, as I understand it the value of count
in the call to printf
may either be zero (it is passed before factorial was called) or may be 10 (the value after factorial was called). Therefore, main could better be written as:
int main(void)
{
int i = 10;
int count = 0;
int fact= factorial(i, &count);
printf("%d Iterations, Factorial of %d is %d\n", count, i, fact);
return 0;
}
6.5.2.2 Function calls: 10 The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.
Upvotes: 1
Reputation: 8614
There are two ways of solving this problem.
e.g.
int factorial(unsigned int i, int *count)
{
static int count2;
*count = ++count2;
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1, count);
}
int main()
{
int i = 10;
int count = 0, fact;
fact = factorial(i, &count);
printf("%d Iterations, Factorial of %d is %d\n", count, i, fact);
return 0;
}
e.g.
int factorial(unsigned int i, int *count)
{
(*count)++;
// Remaining lines the same as first solution.
}
The second solution will only work in some special types of recursive functions where the first function calls the second and the second calls the third, etc. It will not work for example in a recursive fibbonaci sequence algorithm.
The first solution is a more general one, and will work for all conditions.
Upvotes: 0
Reputation: 783
Declare the count
variable as static
inside the factorial function itself.
static int count = 0;
Upvotes: 0
Reputation: 134286
In your first case, factorial()
function, count
is of type int *
. So, while calling the function recursively (in the return
statement), do not pass address of count
, just pass the count
itself.
That said, as count
is to be modified in the function call of factorial()
, don't pass both of them (the variable and the function call which modifies the variable) in the same argument list as there is no sequence point in the elements passed as argument list, so you'll end up invoking undefined behavior.
Upvotes: 0