问题
Imagine a function in those versions:
int faculty(const unsigned int n) {
return n == 1 ? n : n * faculty(n - 1);
}
int faculty(const unsigned int n) {
return n == 1 ? 1 : n * faculty(n - 1);
}
The only difference is that I return n in the first and 1 in the second one, depending on n. The result is the same but is there any other difference you could be aware of while ignoring the significance?
I know there is a high chance the compiler will make the same assembly instructions out of it, but hey, I'm just curious.
回答1:
As has been pointed out in comments, gcc will recognise the two to be identical. For what clang does to the code there is a follow-up question. Apart from clang going havoc, the difference is cosmetic.
There is however a subtle problem in your code. factorial(0) will make n-1 wrap around and recurse till it arrives at n==1 just to return the wrong value: 0 from a 0 * faculty(-1U) in the top-level n==0 call. (0! is defined to be 1).
The two 1s in your code are magic numbers and actually they are two different ones, they just happen to have the same value. One is the condition to stop the recursion, the other is the value you return when recurstion stops. You chose the wrong stop condition. Some may insist that naming those constants is silly, but I think it could have helped to spot that mistake :
int faculty(const unsigned int n) {
const unsigned int stop_when_n_leq = 1;
const int return_at_stop = 1;
return n <= stop_when_n_leq ? return_at_stop : n * faculty(n - 1);
}
Magic numbers are numbers in code without a name. You had two 1s that appeared to be the same, but close inspection shows that those two 1s are actually something different. In/decrementing by one is so common that I do not consider it as being "magic". As with any rule of thumb, you have to decide where to apply it and where not. Perhaps I wouldn't name the constants in such a "simple" function.
来源:https://stackoverflow.com/questions/60773397/using-variable-vs-using-number