C++似乎违反了添加属性

Mat*_*t G 12 c++

在课堂上完成作业,我遇到了这个(请注意循环的条件)

// This one works.
for (int k = 0; k + negwords[j].length() < comments[i].length(); k++) {
    if (comments[i].substr(k, negwords[j].length()) == negwords[j]) {
        negativeScore++;
    }
}
//*/

/*/ This one doesn't: It fails with an out-of-bounds index.
for (int k = 0; k < comments[i].length() - negwords[j].length(); k++) {
    if (comments[i].substr(k, negwords[j].length()) == negwords[j]) {
        negativeScore++;
    }
}
//*/
Run Code Online (Sandbox Code Playgroud)

为什么第一个有效但第二个无效?它是关于操作顺序,bool强制到int,操作员关联性还是OBOE的东西?

Ben*_*igt 33

如果任一negwords[j].length()comments[i].length()返回一个无符号整型至少一样大unsigned int,然后k将晋升为同一无符号类型,以及模加的规则将适用.

作为一个例子,这意味着这1 < 2 - 3是真的,因为2 - 3在模数运算中包裹,变成一个非常大的数字.

如果您感兴趣,此行为在标准的3.9.1节中指定,其中包括以下规则:

无符号整数应遵守算术模2 n的定律,其中n是该特定整数大小的值表示中的位数.

关于影响的脚注:

48这意味着无符号算术不会溢出,因为无法由结果无符号整数类型表示的结果以比模式生成的无符号整数类型所表示的最大值大1的数量减少.


数学家将这种算术知道为伽罗瓦域的代数.在C++中,它用于无符号整数类型.其他类型不使用模运算,但它们也不使用普通的小学算术(形式上,实数的代数),因为正常算术需要密集的不可数数字集,并且有限大小的计算机可以' t表示无限集的成员.

感谢Oliver指出我的错误.GF(2)^ n确实控制了按位运算以及在计算机软件中完成的一大堆其他常见计算,例如CRC.但它没有描述超过1位的无符号算术,因为Galois域上的多项式不"携带".

  • @Cyber​​:不,下溢是`DBL_MIN/2.0*2.0`为零.这是环绕式的. (4认同)