I wrote a function that reverses an integer (123 becomes 321) with recursion, and I was told that using global variables is bad practice, but I'm having trouble figuring out how to get the result from the function without using one. I tried declaring the variable inside the function, but then I get undesired results.
#include <stdio.h>
int result = 0;
int reverse_num(int num)
{
int remainder = num % 10;
if (num == 0) return 0;
result *= 10;
result = remainder;
reverse_num(num / 10);
return result;
}
int main(void)
{
int num, reversed_num;
printf("Insert number: ");
scanf("%d", &num);
reversed_num = reverse_num(num);
printf("Inverted number: %d", reversed_num);
return 0;
}
Thank you for any assistance.
CodePudding user response:
To keep it similar to your original code, only without the global variable, try this:
#include <stdio.h>
int reverse_num(int num)
{
static int result = 0;
int remainder = num % 10;
if (num < 0) {
result = 0;
return 0;
}
if (num == 0) return 0;
result *= 10;
result = remainder;
reverse_num(num / 10);
return result;
}
int main(void)
{
int num, reversed_num;
printf("Insert number: ");
scanf("%d", &num);
reverse_num(RESET);
reversed_num = reverse_num(num);
printf("Inverted number: %d\n", reversed_num);
return 0;
}
Here, I just make result
into a local static
variable in the function, which means it keeps its value even when the function returns (like a global variable, except that its scope is only within the function). The catch is that if you want to call it more than once, you need a way to reset the result
value; I did this by using a negative value for num
as a semaphore to reset.
CodePudding user response:
There are many ways. One way involves finding the most significant decimal digit per each recursion.
Below is an inefficient example.
Works OK for some values 0 to near INT_MAX/10
.
#include <stdio.h>
int reverse_num(int num) {
if (num < 10) {
return num;
}
int pow10 = 10;
while (num/pow10 >= 10) {
pow10 *= 10;
}
int lead_digit = num/pow10;
return reverse_num(num % pow10) * 10 lead_digit;
}
int main() {
printf("%d\n", reverse_num(123456789));
printf("%d\n", reverse_num(1));
printf("%d\n", reverse_num(100));
}
Output
987654321
1
1
Fails for others printf("%d\n", reverse_num(123000789));
--> 987321.
Improved: recursive and efficient.
static int reverse_num_helper(int num, int power10) {
if (power10 < 10) {
return num;
}
return reverse_num_helper(num % power10, power10 / 10) * 10 num / power10;
}
int reverse_num(int num) {
int pow10 = 1;
while (num / pow10 >= 10) {
pow10 *= 10;
}
return reverse_num_helper(num, pow10);
}
int main() {
printf("%d\n", reverse_num(123000789));
printf("%d\n", reverse_num(123456789));
printf("%d\n", reverse_num(123));
printf("%d\n", reverse_num(1));
printf("%d\n", reverse_num(100));
}
Output
987000321
987654321
321
1
1
CodePudding user response:
int Reverse(int n,int Len) {
if (n == 0)
return 0;
return std::pow(10, Len-1)*(n % 10) Reverse(n / 10, Len-1);
}
//inside main
Reverse(54321,5);
//Output Should be 12345
CodePudding user response:
A somewhat more long-winded version of that given by @chux might be a bit clearer.
#include <stdio.h>
int count_places(int num);
int reverse_by_places(int num, int num_places);
int ipow(int base, int power);
int reverse_num(int num)
{
return reverse_by_places(num, count_places(num)) / 10;
}
int ipow(int base, int power)
{
if (power == 0)
return 1;
return base * ipow(base, power-1);
}
int count_places(int num)
{
int i;
if (num == 0)
return 1;
for (i = 0; num > 0; i )
{
num /= 10;
}
return i;
}
int reverse_by_places(int num, int num_places)
{
int dividend = num / 10, remainder = num % 10;
if (dividend == 0)
return remainder * ipow(10, num_places);
else
return ((remainder * ipow(10, num_places)) reverse_by_places(dividend, num_places-1));
}
int main(void)
{
int num, reversed_num;
printf("Insert number: ");
scanf("%d", &num);
reversed_num = reverse_num(num);
printf("Inverted number: %d\n", reversed_num);
return 0;
}
CodePudding user response:
The common way to do this is to have another argument just for the accumulated result. It can be accomplished in C by splitting your function into the one called by the user and the one that does all the work.
int reverse_num_helper(int num, int result)
{
int remainder = num % 10;
if (num == 0) return result;
result *= 10;
result = remainder;
return reverse_num_helper(num / 10, result);
}
int reverse_num(int num)
{
return reverse_num_helper(num, 0);
}
(In C you could combine the two into int reverse_num(int num, int result = 0)
.)
Notice how your function is essentially unchanged.
We made only two minor modifications:
- returning
result
instead of zero whennum
reaches zero - invoking recursion with the modified
result
value
CodePudding user response:
I think I will use pointer in this situation.