在上课时,我遇到了这个(注意循环的条件)
// 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++;
}
}
//*/
为什么第一个有效但第二个无效?它是关于操作顺序,bool强制到int,操作员关联性还是OBOE的东西?
答案 0 :(得分:33)
如果negwords[j].length()
或comments[i].length()
返回的无符号整数类型至少与unsigned int
一样大,那么k
将被提升为相同的无符号类型,并且将适用模块化添加规则。
例如,这意味着1 < 2 - 3
为真,因为2 - 3
包含在模运算中,变得非常大。
如果您感兴趣,此行为在标准的第3.9.1节中指定,其中包括以下规则:
无符号整数应遵守算术模2 n 的定律,其中 n 是该特定大小的值表示中的位数整数。
关于影响的脚注:
48 这意味着无符号算术不会溢出,因为无法用结果无符号整数类型表示的结果是以一个大于可由最大值表示的数量的模数减少的。得到的无符号整数类型。
数学家知道这种类型的算术是 Galois域的代数 。在C ++中,它用于无符号整数类型。其他类型不使用模运算,但它们也不使用普通的小学算术(正式地,实数的代数),因为正常算术需要密集的不可数数字集,并且有限大小的计算机不能代表无限集的成员。
感谢Oliver指出我的错误。 GF(2)^ n确实控制了按位运算以及在计算机软件中完成的一大堆其他常见计算,例如CRC。但它并没有描述超过1位的无符号算术,因为Galois域上的多项式不会“携带”。