首页 > 编程语言 >C++ 不要将有符号整数和无符号整数相加

C++ 不要将有符号整数和无符号整数相加

时间:2024-09-11 14:03:56浏览次数:1  
标签:输出 cout 符号 int unsigned C++ 整数

有符号整数和无符号整数相加时,把负数转换成无符号数类似于直接给无符号数赋一个负值,结果等于这个负数加上无符号数的模。

unsigned int n = 300;
int m = -500;
cout << m + m << '\n';
cout << n + m << '\n';

输出:

-1000        // 正确
4294967096   // 错误

结果做个类型转换后,貌似是对的:

int nm = n + m; 

这样输出nm-200

当有符号的数值绝对值小于等于无符号的时候好像算的是对的(vs2015)。

unsigned int n = 300;
int m = -200;
cout << m + m << '\n';
cout << n + m << '\n';

输出:

-400
100
unsigned int n = 300;
int m = -300;
cout << m + m << '\n';
cout << n + m << '\n';

输出:

-600
0

当从无符号数中减去一个值时,不管这个值是不是无符号数,我们都必须确保结果不能是一个负值:

unsigned ul=42, u2=10;
std::cout<<ul-u2<< std::endl;//正确:输出 32
std::cout<<u2-ul<< std::endl;//正确:不过,结果是取模后的值 4294967264

输出:

32
4294967264

无符号数不会小于0这一事实同样关系到循环的写法。例如,在 1.4.1节的练习(第11页)中需要写一个循环,通过控制变量递减的方式把从10到0的数字降序输出。这个循环可能类似于下面的形式:

// 这个时对的
for(inti=10;i>=0;--i)
    std::cout<<i<< std::endl;

下面这种写法永远退不出循环:

//错误:变量u永远也不会小于0,循环条件一直成立
for(unsignedu=10;u>=0;--u)
   std::cout<<u<< std::endl;

所以,一定不要混用无符号整数和有符号整数,不能将负数赋值给无符号变量。

相乘,也是不对的。

unsigned a = 1;
int b = -1;
cout << a * b << '\n';

输出:

4294967295    // 不对,你可能期望的时 -1。将这个数强转成有符号,它就是 -1。




参考:《C++ Primer》 P34

标签:输出,cout,符号,int,unsigned,C++,整数
From: https://www.cnblogs.com/huvjie/p/18408134

相关文章

  • 南沙C++信奥老师解一本通题:1203:扩号匹配问题
    ​【题目描述】在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$"标......
  • C++题目收集2
    这是本专栏的的第二篇收录集,我们一起来看一看那些有意思的题目,拓宽自己的思路。本期的题目有一些难,所以数目少一点。题目一:约瑟夫环#include<iostream>#include<vector>intjosephus(intn,intm){std::vector<int>people(n);for(inti=0;i<n;++i)......
  • 《C++ Primer Plus》学习day3
    C++11新增的内容:char16_t和char32_tchar16_t:无符号,16位,使用前缀u表示char_16字符常量和字符串常量;char32_t:无符号,32位,使用前缀U表示char32_t常量浮点类型C++有三种浮点类型:float、double、longdouble头文件cfloat中对对浮点数进行了限制:比如最低有效位......
  • C++入门 一(命名空间,缺省参数,超详细!!!)
    文章目录C++与C语言的区别命名空间(Namespace)缺省参数C++与C语言的区别C++在保留了C语言所有特性的基础上增加了面向对象编程的支持,并引入了更多的高级特性和工具来提高代码的可读性、可维护性和可扩展性。而C语言则更加简洁和底层,适用于对性能要求极高或对内存管理......
  • c++引用
    c++指针和引用的区别指针和引用在C++中都用于间接访问变量,但它们有一些区别:指针是一个变量,它保存了另一个变量的内存地址;引用是另一个变量的别名,与原变量共享内存地址。指针(除指针常量)可以被重新赋值,指向不同的变量;引用在初始化后不能更改,始终指向同一个变量。指针可以为......
  • C++入门知识
    命名空间为什么会有命名空间?解决C语言中命名冲突的问题。(std是所有c++库的命名空间)解决方法:采用域作用限定符(::):指定编译器搜索的位置。编译器默认的搜索顺序:先局部再全局。命名空间域大体有4种域:全局域、局部域、命名空间域、类域。命名空间域的特点:1.不会影响生命......
  • 挑战不可能篇1——洛谷28分钟14道CCF GESP C++ 一级上机题&洛谷14道题题解
    扯谈今天继续挑战不可能:洛谷28分钟14道题这我个人认为不简单,算上编译、提交、命名等杂七杂八的东东之后,只剩下了大约1分钟/题。本次挑战的是CCFGESPC++一级上机题.这竟然能成功!下面附上每一题第一题第二题第三题第四题第五题第六题第七题第八题第九题第十题......
  • 【C++ Primer Plus习题】14.3
    大家好,这里是国中之林!❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看←问题:解答:main.cpp#include<iostream>#include"queuetp.h"usingnamespacestd;intmain(){ Queue......
  • 【自用20.】C++析构函数
    作用对象销毁前,做清理工作。具体的清理工作,一般和构造函数对应比如:如果在构造函数中,使用new分配了内存,就需在析构函数中用delete释放。如果构造函数中没有申请资源(主要是内存资源),那么很少使用析构函数。函数名:~类型名没有返回值,没有参数并且最多只能有一个析构函数......
  • 【自用19.3】C++构造函数复盘
    定义一个“人”类#include<iostream>#include<Windows.h>#include<string>usingnamespacestd;//定义一个“人类”classHuman{public://公有的,对外的 voideat();//方法,“成员函数” voidsleep(); voidplay(); voidwork(); stringgetName(); in......