以下代码有效,但我不太明白 *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/