C++ 无符号和有符号比较

C++ 无符号和有符号比较,c++,C++,下面是非常简单的代码 #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; } #包括 使用名称空间std; int main()

下面是非常简单的代码

#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;
}
#包括
使用名称空间std;
int main(){
无符号整数u=10;
int i;
整数计数=0;

for(i=-1;i其原因是-1被强制转换为无符号int,因此for循环代码永远不会执行

尝试使用-Wall-Wextra进行编译,这样您就可以得到相应的警告(如果到目前为止还没有得到警告,请使用g++进行编译)


在比较过程中,
的两个操作数(i在一个以4字节存储整数的系统上,我相信-1的值等于2147483649(1000 0000 0001)的值)-它是1,MSB设置为1表示它为负。

这是因为在比较之前,
i
被提升为无符号值。这将把它设置为
UINT_MAX
,在32位机器上等于
4294967295
。因此,您的循环基本上与以下内容相同:

// will never run
for (i = 4294967295; i <= u; i++) {
    count++;
}
//将永远不会运行

对于(i=4294967295;谢谢你,我只想问你一件事,我会给你我的问题的链接,请告诉我为什么他们会降低我的分数或者他们会否决我的投票,好吗?我想有好的声誉分数并尝试发布好的问题,但他们会降低it@davit:你的另一个问题被否决了,因为编译器准确地告诉了你什么是wrong(您缺少一个分号)但是您在这里发布了您的问题,甚至没有亲自尝试解决问题。您的规则不起作用。实际上添加了2**32,即
UINT_MAX+1
,而不是
UINT_MAX-1
。在您的新注释中,从已签名到未签名的转换对所有输入都有明确的定义,但是从未签名到已签名的转换可以调用实现定义的行为(这里不是,因为
u
的值是10,适合
int
)是的,当我建议对
u
使用或强制转换为有符号整数时,假设
u
保持在有符号整数的允许范围内。如果你可能超过这个范围,并且你真的需要无符号,你将不得不重新思考代码,就像不在负1开始
I
一样。不,在2的补码表示中离子<代码> -1 < /COD>作为所有的存储。但是实际的表示并不重要,因为C++标准定义了从符号到无符号整数类型的转换,作为模块BASE-N算法的一致性。在符号大小系统中,这是正确的,这是非常罕见的。最合理的当前系统使用2的混合。表示整数的整数,在这种情况下-1将由设置为1的所有位表示(在这种情况下,从有符号到无符号的转换根本不需要更改数据,只需要更改数据的解释方式).@Jerry:符号大小一点也不罕见。IEEE 754需要它。几乎每台计算机都使用两个补整数和符号大小浮点表示。@Ben:是的,如果你费心读第二句话,那就很明显了,我说的是整数,而不是浮点。@Jerry:我明白。但我不知道让一些计算机工程专业的学生看到这条线索并说:“我不想费心去学习符号幅度算术是如何工作的,因为反正没人用它。”。另一方面,您应该使用
std::endl
而不是将
\n
插入流中,因为
std::endl
两者都是可移植的,并且可以确保立即显示输出。@Ben:
\n
也是可移植的;如果您现在特别想刷新流,您应该只使用
endl
\n
是portable(它被转换为平台的换行序列),并且不承担立即刷新流的开销。您应该使用具有您想要的语义的流:如果您想要刷新流,请使用
endl
,如果您只想要换行,请使用
\n
。std::endl相当于“\n”