Lewis
Lewis

Reputation: 175

Recursive addition code in C

The following code works but I don't quite understand how *if (s == 0) works. It checks if the string is 0?

Also for return(isnumber(s+1)) what is the logic behind that? I know s is a string but I can just pass s+1 into a function? How does it even know what character I'm looking for?

int isnumber(char *s) {
    if (*s == 0) {
        return 1;  /* Reached end, we've only seen digits so far! */
    }
    if(!isdigit(*s)) {
        printf("The number is invalid\n");
        return 0;  /* first character is not a digit, so no go */
    }
    return(isnumber(s+1));
}


int main () {
    char inbuf[LENGTH];
    int i, j;

    printf("Enter a string > ");
    fgets(inbuf, LENGTH-1, stdin); // ignore carriage return
    inbuf[strlen(inbuf)-1] = 0;
    j = isnumber(inbuf);
....
}

Upvotes: 0

Views: 81

Answers (3)

Icemanind
Icemanind

Reputation: 48686

This function is a recursive function that checks if a string contains all numbers. To understand how the code works, you must understand how C stores strings. If you have the string "123", C stores this string in memory, like this:

|-----------------------------------|
| 0x8707 | 0x8708 | 0x8709 | 0x870A | 
|--------|--------|--------|--------|
|        |        |        |        |
|  '1'   |  '2'   |  '3'   | '\0'   |
|-----------------------------------|

What C does is it breaks your sting up into characters, stores them in some arbitrary location in memory and adds a null character (\0) (ASCII 0) to the end of the string. This null character is how C knows where the string ends.

Your isnumber() function takes a char *s as a parameter. This is called a pointer. Internally, whats going on is your main() function calls isdigit() and it actually passes in the address of your string, not the string itself. This is important:

j = isnumber(inbuf);

How the compiler interprets this is call isnumber() and pass along the address of inbuf and assign the return value to j.

Now back up at the isnumber() function, its receiving the address of inbuf and assigning it to s. By placing an asterisk (*) in front of s, you are doing something called dereferencing s. Dereferencing means you want the value contained at the address of s. So the line that says if (*s == 0) is basically saying If the value contained at the address of s is equal to 0. Remember earlier I told you in memory, strings always have a terminating null (\0) character? This is how your function knows to end and return.

The next thing to understand is pointer arithmetic. Depending on your system, a char might occupy either 1 byte of memory or 2 bytes. You can find out for sure by printing a sizeof(char). But when you refer to (s+1), that is telling the computer to take the memory address pointed to by s and add to it whatever the size of a char is. So if a char is 1 byte long and s is pointed to 0x8707, then (s+1) will make s equal 0x8708 and *s will point to the '2' in our string (see my memory block diagram above). This is how we iterate through each character in the string.

Hopefully this clears up the confusion!

Upvotes: 4

Carey Gregory
Carey Gregory

Reputation: 6846

The statement if (*s == 0) checks to see if the char s points to is zero. In other words, it checks to see if s is a zero-length string and returns 1 if so.

The statement return (isnumber(s+1)) adds 1 to s, causing it to point to the second char in the string, and passes that to isnumber(). isnumber returns true if the string at s[1] is a digit.

Upvotes: 1

Steve Wellens
Steve Wellens

Reputation: 20620

In C, strings are terminated with a null character.

(*s == 0) is checking for the null terminator.

This code is a little weirder.

return(isnumber(s+1));

Since the current character is a digit, keep going...call the function again starting at the NEXT character. This is a recursive function call and there is really no need when iteration would be simpler.

Upvotes: 0

Related Questions