这里是非常简单的代码:
#include <iostream>
using namespace std;
int main() {
unsigned int u=10;
int i;
int count=0;
for (i=-1;i<=u;i++){
count++;
}
cout<<count<<"\n";
return 0;
}
计数器的值为0。为什么?
这里是非常简单的代码:
#include <iostream>
using namespace std;
int main() {
unsigned int u=10;
int i;
int count=0;
for (i=-1;i<=u;i++){
count++;
}
cout<<count<<"\n";
return 0;
}
<=
的两个操作数必须提升为相同的类型。显然它们被提升为unsigned int
(我没有标准规则在手边,我会在一秒钟内查找)。由于(unsigned int)(-1) <= u
是假的,因此循环永远不会执行。(i <= u)
时,i
被升级为无符号整数,并在此过程中将 -1 转换为 UINT_MAX。UINT_MAX + 1
,而不是 UINT_MAX - 1
。 - Ben Voigtu
的值为10,适合于int
)。 - Ben Voigtu
使用或转换为有符号整数时,这是假设 u
仍然在有符号整数允许的范围内。如果您可能会超过这个范围,并且确实需要无符号整数,那么您将不得不重新考虑代码 - 例如,可能不要从负一开始 i
。 - thomasrutteri
被提升为无符号值。这将把它设置为 UINT_MAX
的值,在 32 位机器上等于 4294967295
。因此,你的循环本质上与以下代码相同:// will never run
for (i = 4294967295; i <= u; i++) {
count++;
}
这是因为-1被强制转换为无符号整数,所以for循环代码永远不会被执行。
尝试使用-Wall -Wextra编译,这样您就可以获得相应的警告(如果到目前为止没有收到它们,并且使用g++编译)
std::endl
而不是将\n
插入到流中,因为std::endl
既具有可移植性,又确保输出立即显示。 - Ben Voigt\n
同样具有可移植性;只有在你特别想立即刷新流时才应该使用endl
。 - Mike Seymour\n
是可移植的(它会被转换成平台的换行序列),并且不需要立即刷新流的开销。你应该使用具有你想要语义的那个:如果你想要刷新流,请使用endl
,如果你只想要一个换行,请使用\n
。 - jalf