c - C中的递归加法代码

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

最佳答案

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

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

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

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

j = isnumber(inbuf);

编译器如何解释这是调用 isnumber() 并传递 inbuf 的地址并将返回值分配给 j

现在回到 isnumber() 函数,它接收 inbuf 的地址并将其分配给 s。通过在 s 前面放置一个星号 (*),您正在执行称为取消引用 s 的操作。取消引用意味着您想要包含在 s 地址中的值。所以 if (*s == 0) 这行基本上是在说 如果 s 地址中包含的值等于 0。还记得我之前在内存中告诉过你,字符串总是有一个终止的空 (\0) 字符吗?这就是您的函数知道结束和返回的方式。

接下来要了解的是指针运算。根据您的系统,char 可能占用 1 个字节或 2 个字节的内存。您可以通过打印 sizeof(char) 来确定。但是,当您引用 (s+1) 时,这就是告诉计算机获取 s 指向的内存地址,并将 的大小添加到其中>char 是。所以如果 char 是 1 个字节长并且 s 指向 0x8707,那么 (s+1) 将使 s 等于 0x8708 并且 *s 将指向我们字符串中的“2”(参见上面我的内存框图)。这就是我们如何遍历字符串中的每个字符。

希望这能消除困惑!

关于c - C中的递归加法代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27411673/

相关文章:

c- 在函数中分配结构成员时出错

c - 如何使用 `FindResourceEx()` 和 `LoadResource()` 加载新菜单?

c - C 预处理器与变量和函数连接时出错(在 for 循环中动态索引)

c - 加载 DLL 库

c++ - 有符号整数类型的最大值

c - 如何编写处理大数的解决方案?

c - 关于为什么我的程序返回错误答案的任何解决方案?

c - SerialBT.readString() 保存为字符串

c - linux,write()系统调用在尝试写入文件时返回-1

c - `close(fd)` 是否破坏文件表条目和/或 vnode 表条目?