目前我正在编写一个程序,在这个程序中我需要一个变量count
,每次调用该函数时它都会递增。在我的例子中,我有一个递归函数,想知道程序执行了多少迭代。
我通过计算数字的阶乘来简化代码。
我的第一种方法不起作用,最后会收到警告信息:
#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
我的第二种方法也不起作用,但也没有任何警告信息。
#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;
}
如何让它运行?有任何想法吗?我使用Ubuntu和gcc。
答案 0 :(得分:1)
正如其他解决方案所暗示的那样,不需要静态变量。以下是正确的:
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;
}
一个注意事项:由于printf
语句中的参数评估顺序无法保证,据我所知,count
调用中printf
的值可能为零(它在调用阶乘之前传递)或者可能是10(在调用阶乘之后的值)。因此,main最好写成:
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函数调用:10函数指示符的评估顺序,实际参数和实际参数中的子表达式是未指定的,但在实际调用之前有一个序列点。
答案 1 :(得分:0)
在您的第一个案例中,factorial()
函数count
的类型为int *
。因此,在递归调用函数时(在return
语句中),不要传递count
的地址,只需传递count
本身。
也就是说,因为count
要在factorial()
的函数调用中进行修改,所以不要传递它们(变量和修改变量的函数调用)相同的参数列表,因为作为参数列表传递的元素中没有序列点,因此您最终会调用undefined behavior。
答案 2 :(得分:0)
在factorial函数本身内将count
变量声明为static
。
static int count = 0;
答案 3 :(得分:0)
有两种方法可以解决这个问题。
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.
}
第二个解决方案只适用于某些特殊类型的递归函数,其中第一个函数调用第二个函数,第二个函数调用第三个函数,等等。例如,在递归的fibbonaci序列算法中,它不起作用。
第一种解决方案更为通用,适用于所有条件。