2017-02-21 72 views
0

这里是一个循环,通过C串向后推移:比较无符号的表达与0

size_t slen = strlen(string); 
for (size_t i = slen-1; i >= 0; i--) { 
    /* do stuff */ 
} 

当我编译此代码与gcc -Wall -Wextra -std=c99 -o code code.c,收到这样的警告:

警告:比较无符号表达式> = 0始终为真[-Wtype-limits]

在处理此警告时,我将此循环替换为:

for (int i = (int)slen-1; i >= 0; i--) { 

哪些工作正常,但我想知道如果他们是一种方式来使第一个循环仍然编译没有上述警告?当我用-Wextra进行编译时,似乎只会触发此警告。

+3

为什么要让第一次循环编译时没有警告?警告告诉你,这在逻辑上是不正确的。所以不知道你试图通过试图保持不正确的代码来实现。 – kaylum

+0

@ kaylum只是因为好奇而好奇。在阅读更多内容之后,我必须同意您的看法,即不正确的代码。 – RoadRunner

+1

编译第一个循环有什么意义?一个无符号变量总是'> = 0',所以为什么还要检查? –

回答

2

无符号整数不能小于0。这就是“无符号”的意思。所以显然你的循环永远不会终止。

相反,你可以使用:

for (size_t i = slen; i-- > 0;) { 

这递减i之前进行测试,因此该循环的最后一次迭代将与i == 0发生,那么测试i-- > 0失败,打破了循环。

Related thread

+0

干杯@ M.M,你的解释是有道理的:) – RoadRunner

2

这里真正的犯罪是你违反了所有循环往前走的规则,即使是那些倒退的规则。循环应该写成如下:

for (size_t i = 0, e = strlen(string); i != e; ++i) { 
    const size_t ri = e - i - 1; 

    /* do stuff with index ri */ 
} 

这种结构使得对迭代器对反向迭代关系明显− 1偏移,避免了任何的符号性问题,并为您提供一个免费的轮计数器。

+0

是的,我想我没有仔细研究它是如何写的。感谢您的解释,但它非常有帮助:)。 – RoadRunner

相关问题