C中的递归加法代码

时间:2014-12-10 22:02:02

标签: c

以下代码有效,但我不太明白 * if( s == 0) 的工作原理。 它检查字符串是否为0?

return(isnumber(s + 1)) 背后的逻辑是什么? 我知道s是一个字符串,但我可以将s + 1传递给函数?它怎么知道我在找什么角色?

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);
....
}

3 个答案:

答案 0 :(得分:4)

此函数是一个递归函数,用于检查字符串是否包含所有数字。要了解代码的工作原理,您必须了解C如何存储字符串。如果你有字符串" 123",C将这个字符串存储在内存中,如下所示:

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

C的作用是将它们分解为字符,将它们存储在内存中的任意位置,并在字符串的末尾添加空字符(\0)(ASCII 0)。这个空字符是C知道字符串结束的位置。

您的isnumber()函数将char *s作为参数。这称为指针。在内部,最新进展的是main()函数调用isdigit(),它实际上是传入地址您的字符串,而不是字符串本身。这很重要:

j = isnumber(inbuf);

编译器如何解释这是call isnumber() and pass along the address of inbuf and assign the return value to j

现在备份到isnumber()功能,它接收inbuf的地址并将其分配给s。通过在(*)前放置一个星号s,您正在执行一项名为取消引用 s的操作。解除引用意味着您希望包含在s地址中的值。所以说if (*s == 0)的行基本上是If the value contained at the address of s is equal to 0。记得早些时候我在内存中告诉过你,字符串总是有一个终止的空(\0)字符?这就是你的函数知道结束和返回的方式。

接下来要理解的是指针算术。根据您的系统,char可能占用1个字节的内存或2个字节。您可以通过打印sizeof(char)来确定。但是当你引用(s+1)时,它告诉计算机取s指向的内存地址,并添加char的大小。因此,如果char长度为1个字节且s指向0x8707,那么(s+1)将使s等于0x8708和{{1}将指向' 2'在我们的字符串中(参见上面的内存框图)。这就是我们如何遍历字符串中的每个字符。

希望这可以解决困惑!

答案 1 :(得分:1)

语句if (*s == 0)检查char s指向的是否为零。换句话说,它会检查s是否为零长度字符串,如果是则返回1

语句return (isnumber(s+1))1添加到s,使其指向字符串中的第二个char,并将其传递给isnumber()。如果isnumber处的字符串是数字,则s[1]返回true。

答案 2 :(得分:0)

在C中,字符串以空字符终止。

(*s == 0)正在检查空终止符。

这段代码有些怪异。

return(isnumber(s+1));

由于当前字符是一个数字,所以继续...从NEXT字符开始再次调用该函数。这是一个递归函数调用,当迭代变得更简单时,确实没有必要。