Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 正在将无符号表达式与0进行比较_C - Fatal编程技术网

C 正在将无符号表达式与0进行比较

C 正在将无符号表达式与0进行比较,c,C,下面是一个反向遍历C字符串的循环: 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

下面是一个反向遍历C字符串的循环:

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
编译时触发

无符号整数不能小于
0
。这就是“未签名”的意思。显然,你的循环永远不会结束

相反,您可以使用:

for (size_t i = slen; i-- > 0; ) {
这将在递减
i
之前执行测试,因此循环的最后一次迭代将在
i==0
时进行,然后测试
i-->0
失败,从而中断循环


.

无符号整数不能小于
0
。这就是“未签名”的意思。显然,你的循环永远不会结束

相反,您可以使用:

for (size_t i = slen; i-- > 0; ) {
这将在递减
i
之前执行测试,因此循环的最后一次迭代将在
i==0
时进行,然后测试
i-->0
失败,从而中断循环


.

这里真正的罪过是你违反了所有循环向前的规则,即使是那些向后的循环。循环应按如下方式编写:

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

    /* do stuff with index ri */
}

这种结构使得−1-迭代器的偏移量用于反转迭代器关系显然,它避免了任何符号问题,并免费为您提供了一个整数计数器。

这里真正的罪过是您违反了所有循环向前的规则,即使是那些向后的循环。循环应按如下方式编写:

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
,那么为什么还要麻烦检查呢?为什么要让第一个循环在没有警告的情况下编译?正如警告告诉您的那样,它在逻辑上是不正确的。因此,不确定您试图通过保留不正确的代码来实现什么。编译第一个循环有什么意义?一个无符号变量总是
=0
,那么为什么还要费心检查呢?@KerrekSB你能详细说明一下
所有循环前进的规则吗?@dualed:嗯,你应该将范围内的所有循环概念化为具有相同的基本结构“在一个范围内迭代”,因此它们都应该采用相同的一般形式。当然,这不是语言要求,而是模式间规则性意义上的“规则”:从范围的开头开始,一直走到终点。这是否意味着在其他范围内倒退,或者大步前进,最终是一个细节,因此我认为细节不应该出现在循环头中,循环头应该一直向前。它不是100%,但在很多情况下都有效谢谢,所以它更多的是一种模式而不是一种规则,除了假定的可读性之外没有任何不良影响?是的,对,它更多的是一种如何概念化事物的规则,而不是语言规则。类似于,比方说,五法则。五法则是标准库如何定义隐式内存管理操作符的逻辑结果,我不会把它称为一个概念。。。它也有著名的出版物(比如在isocpp.org上)和你的。。。我在上面找不到任何东西,ofc的“所有循环向前的规则”并不是一个很容易搜索的术语。我总是对新的想法和最佳实践持开放态度(这就是为什么我问你这个问题),但是为了消化这一点,我觉得我需要一个更坚实的基础来接受它。“KerrekSB,你能详细阐述<代码>所有循环前进的规则< /代码>吗?”您应该将范围上的所有循环概念化为具有相同的“在范围上迭代”基本结构,因此它们都应该采用相同的一般形式。当然,这不是语言要求,而是模式间规则性意义上的“规则”:从范围的开头开始,一直走到终点。这是否意味着在其他范围内倒退,或者大步前进,最终是一个细节,因此我认为细节不应该出现在循环头中,循环头应该一直向前。它不是100%,但在很多情况下都有效谢谢,所以它更多的是一种模式而不是一种规则,除了假定的可读性之外没有任何不良影响?是的,对,它更多的是一种如何概念化事物的规则,而不是语言规则。类似于,比方说,五法则。五法则是标准库如何定义隐式内存管理操作符的逻辑结果,我不会把它称为一个概念。。。它也有著名的出版物(比如在isocpp.org上)和你的。。。我在上面找不到任何东西,ofc的“所有循环向前的规则”并不是一个很容易搜索的术语。我总是乐于接受新的想法和最佳实践(这就是为什么我问你这个问题),但为了消化这一点,我觉得自己需要一个更坚实的基础来接受它作为明智的。