我有一个简单的程序,其中包含一个函数来检查 C 字符串是否只有整数,如果有则返回 true (1)
或 false (0)
:
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
bool isStrWholeNumber(const unsigned char *s) {
if (*s == '\0') return false;
while (isdigit(*s++));
if (*s == '\0') return true;
return false;
}
int main()
{
unsigned char str[] = "a";
bool b = isStrWholeNumber(str);
printf("%d\n", b);
return 0;
}
指针自增*s++
应该将自增前的值传递给isdigit
函数,但似乎是传递自增后的值,所以它传递的是字符'\0' 而不是 'a',因为该函数返回 true。
更改函数以在函数调用之外递增指针,有效,对于字符“a”返回 false:
bool isStrWholeNumber(const unsigned char *s) {
if (*s == '\0') return false;
while (isdigit(*s)) s++;
if (*s == '\0') return true;
return false;
}
为什么 while (isdigit(*s++));
不起作用?
结论
这就是当你累了或者睡不好的时候会发生的事情,你最终会犯这样的错误。正如您在答案中看到的那样,该程序运行正常。
休息了一段时间后,我回到这个函数并得到了一个很好的结果,又快又小,正如我想要的那样。我使用 GCC 分析器和 gprof 来测试性能,并检查了程序集的性能和代码大小。在使用和不使用 GCC 优化 -O3 的情况下进行了测试。
这是带注释的结果,以便您理解:
bool isStrWholeNumber(const unsigned char *s) {
if (*s) { // Check if string is not empty
--s; // Decrement pointer. It will be incremented in while bellow
while (isdigit(*++s)); // Iterate over string until a non digit character is found
return !*s; // Returns 1 if end of string was reached, else, return 0
}
return false; // Always returns false if string is empty
}
也许这个功能可以进一步优化,但我不知道如何优化。
由于易读性差,许多糟糕的代码认为该函数,不要到处使用它。
最佳答案
程序正在正常运行。在第一个代码中,isdigit(*s++)
将返回 0
并且 s
将递增,语句 if (*s == '\0') 返回 true;
将返回 true
。
在第二个代码段中,*s++
将不会被求值,并且语句 return false;
将返回 false
。
关于C - while 循环内 isdigit() 调用后递增的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31062209/