Reputation: 4037
In order to learn recursion, I want to count the number of decimal digits that compose an integer. For didactic purposes, hence, I would like to not use the functions from math.h
, as presented in:
I tried two ways, based on the assumption that the division of an integer by 10
will, at a certain point, result in 0
.
The first works correctly. count2(1514, 1)
returns 4
:
int count2(int n, int i){
if(n == 0)
return 0;
else
return i + count2(n / 10, i);
}
But I would like to comprehend the behavior of this one:
int count3(int n, int i){
if(n / 10 != 0)
return i + count3(n / 10, i);
}
For example, from count3(1514, 1);
I expect this:
1514 / 10 = 151; # i = 1 + 1
151 / 10 = 15; # i = 2 + 1
15 / 10 = 1; # i = 3 + 1
1 / 10 = 0; # Stop!
Unexpectedly, the function returns 13
instead of 4
. Should not the function recurse only 3 times? What is the actual necessity of a base case of the same kind of count2()
?
Upvotes: 1
Views: 6605
Reputation: 522
I don't think you need that i+count() in the recursion. Just 1+count() can work fine...
#include <stdio.h>
#include <stdlib.h>
static int count(), BASE=(10);
int main ( int argc, char *argv[] ) {
int num = (argc>1?atoi(argv[1]):9999);
BASE= (argc>2?atoi(argv[2]):BASE);
printf(" #digits in %d(base%d) is %d\n", num,BASE,count(num)); }
int count ( int num ) { return ( num>0? 1+count(num/BASE) : 0 ); }
...seems to work fine for me. For example,
bash-4.3$ ./count 987654
#digits in 987654(base10) is 6
bash-4.3$ ./count 123454321
#digits in 123454321(base10) is 9
bash-4.3$ ./count 1024 2
#digits in 1024(base2) is 11
bash-4.3$ ./count 512 2
#digits in 512(base2) is 10
Upvotes: 0
Reputation: 7815
If you do not provide a return
statement the result is indeterminate.
On most architectures that mean your function returns random data that happens to be present on the stack or service registers.
So, your count3()
function is returning random data when n / 10 == 0
because there is no corresponding return
statement.
Edit: it must be stressed that most modern compilers are able to warn when a typed function does not cover all exit points with a return
statement.
For example, GCC 4.9.2 will silently accept the missing return
. But if you provide it the -Wreturn-type
compiler switch you will get a 'warning: control reaches end of non-void function [-Wreturn-type]' warning message. Clang 3.5.0, by comparison, will by default give you a similar warning message: 'warning: control may reach end of non-void function [-Wreturn-type]'. Personally I try to work using -Wall -pedantic
unless some required 3rd party forces me to disable some specific switch.
Upvotes: 3
Reputation: 13924
Not returning value in a value-returning function is Undefined behavior. You should be warned on this behavior Your logic is also wrong. You must return 1 when `(n >= 0 && n / 10 == 0) and
if(n / 10 != 0)
return i + count3(n / 10, i);
else if (n >= 0) return 1;
else return 0;
Upvotes: 2
Reputation: 1108
In recursion there should be base conditions which is the building block of recursive solution. Your recursion base doesn't return any value when n==0
— so the returned value is indeterminate. So your recursion count3
fails.
Upvotes: 3