C语言中 有符号数、无符号数、整数溢出 (转)
- #include<stdio.h>
- void main()
- {
- int l=-1;
- unsigned int c=135;
- printf("%u\n",l+c);
- }
这个的结果134,而不是我之前认为的很大的正数,实际上需要注意的是-1(0xffffffff)被提升为unsigned int后是一个差1就溢出的unsigned int,所以相加后结果是134。但是如果l=-10000,那么结果就真是一个很大的正数了,因为不涉及溢出了。
C语言中存在两种整数算术运算,有符号型和无符号型。无符号数运算:所有无符号数运算都是以2的n次方为模,(n是结果中的位数)。所以它不存在运算时的没有那种所谓的“溢出”,当它超过范围时,从零开始重新计数!当一个无符号数和有符号数计算的时候,有符号数会自动转化为无符号数参与运算!有符号数运算:
是可能发生“溢出”的,而且“溢出”的结果不固定。
关于无符号数减去无符号数的用法错误:
if ( i - j >=0)
假如i,j为无符号数,这样写可能会引发错误,即当i小于j的时候,这个式子仍然成立,因为无符号数始终是大于等于零的。例: if ( strlen(
a ) >= 10) 与 if (strlen ( b ) -10 >= 0) 这两条语句是不相等的
,因为strlen函数返回的是无符号数类型。
2015年3月8日追加一点:今天看这个地方有些不明白在网上搜了一下资料发现,无符号数相减,如果被减数小于减数,那么结果会是一个非常大的无符号数,而不是一个想象中的有符号数。所以对于无符号数相减之前需要进行判断,最好做比较的时候使用 if ( strlen( a ) >= 10) 这种方式,而不要使用if
(strlen ( b ) -10 >= 0) 这种方式。因为无符号数进行计算的结果还是无符号数;另外无符号数和有符号数计算时,有符号数会被强制转提升无符号数。
例如以下这个例子很有意思:
- #include<stdio.h>
- int main()
- {
- unsigned int a=6;
- int b=-20;
- printf("%d\n",(a+b)>0);
- }
这个小例子可以机器试一下。另外还有几道题不错我也附在最后。
需要注意一点,我在进行程序编写的时候发现一个小问题:
那么unsigned char与signed int相减呢?
- #include<stdio.h>
- void main()
- {
- unsigned char a;
- int b;
- a=0;
- b=2;
- printf("X=%d\n",(a-b)>0);
- }
ANSI C规定在无符号整数和有符号整数之间进行强制类型转换时,位模式不应该改变。类型转换并未改变对象的位模式,改变的是位模式的解释方式。
有符号数转换为无符号数时,负数转换为大的正数(可以理解为原值加上2的n次方),而正数保持不变。
无符号数转换为有符号数时,对于小的数将保持原值,对于大的数则转换为负数(可以理解为原值减去2的n次方)。
今晚在看C的时候突然想到如果把大于unsigned int的范围的数据赋予 该类型变量,printf出来会是什么样。
- void main()
- {
- unsigned int a;
- a=7000000000;
- printf("a=%d\n",a);
- printf("a=%u\n",a):
- }
这两个结果是完全不一样的。
几个小例子:
题目一:
int a = -1;
unsigned int b = 1;
printf("%d", a > b);
结果输出:1
因为无符号数与有符号数比较时,要将有符号数转化为无符号数,再来比较。a转化为无符号数后就是0xFFFFFFFF,肯定大于b
题目二:
char a = -1;
unsigned char b = 1;
printf("%d", a > b);
结果输出:0
奇怪了,怎么会这样?这是因为两者被提升为int了,a提升为int就表示-1,b提升为int 就是1,前者小于后者。注意了这里不是像题目一里一样简单的把char转化为unsigned char了
题目三:
int a = -1;
unsigned char b = -1;
printf("%d\n", a < b);
结果输出是:1
原因在于要把b提升为int就是255当然大于-1了,unsigned char 先提升为int,送入int的低八位中,高位全部补零。
题目四:
char a = -1;
unsigned int b = -1;
printf("%d\n", a == b);
结果输出:1
原因是char类型被扩展为unsigned int后与b相等,同为0xFFFFFFFF
小于int的提升到int,int之后都是从signed -> unsigned
对于浮点数来说,浮点数(float,double)实际上都是有符号数,unsigned 和signed前缀不能加在float和double之上,当然就不存在有符号数根无符号数之间转化的问题了。
一定要记住如果需要使用有符号数时不要忘记强制转换
C语言中 有符号数、无符号数、整数溢出 (转)的更多相关文章
- 2_C语言中的数据类型 (四)整数与无符号数
1.1 sizeof关键字 sizeof是c语言关键字,功能是求指定数据类型在内存中的大小,单位:字节 sizeof与size_t类型 1.1 int类型 1.1.1 ...
- C语言中限定符的作用
C语言中常用的一般包括const.static.extern.register和volatile这几个.这些是C语言标准中规定的关键词,所有的编译器都必须支持这些关键词,它们的作用如下: 1.cons ...
- 程序员---C语言细节7(增加两个整数溢出检测)
主要内容:增加两个整数溢出检测 #include <stdio.h> #include <limits.h> int main(int argc, char *argv[]) ...
- Qt之C语言有符号数与无符号数运算
以32位的stm32f4为例: 1. uint32_t t_int_k = 239773, t_int_km1 = 4294859707; 则t_int_k - t_int_km1 > 0; ...
- C语言中续行符“\”说明
把一个预处理指示写成多行要用“\”续行,因为根据定义,一条预处理指示只能由一个逻辑代码行组成. 而把C代码写成多行则不必使用续行符,因为换行在C代码中只不过是一种空白字符,在做语法解析时所有空白字符都 ...
- C语言中无符号数和有符号数之间的运算
C语言中无符号数和有符号数之间的运算 C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算当然是返回0或1了. un ...
- 【C语言学习趣事】_33_关于C语言和C++语言中的取余数(求模)的计算_有符号和无符号数的相互转换问题
最近再次复习C++语言,用的教材是<C++ Primer>这本教材, 看到第二章的时候,里面有个问题困扰了我. 于是想上网查查怎么回事, 结果看了很久都没有得到一个满意的答案. 书上有这么 ...
- 深入理解计算机系统(2.5)------C语言中的有符号数和无符号数以及扩展和截断数字
上一篇博客我们讲解了计算机中整数的表示,包括无符号编码和补码编码,以及它们之间的互相转换,个人觉得那是非常重要的知识要点.这篇博客我们将介绍C语言中的有符号数和无符号数以及扩展和截断数字. 1.C语言 ...
- c语言中为什么左移不分符号数无符号数,而右移分呢??
因为在C语言标准中,只规定了无符号数的移位操作是采用逻辑移位(即左移.右移都是使用的逻辑左移和逻辑右移).而对于有符号数,其左移操作还是逻辑左移,但右移操作是采用逻辑右移还是算术右移就取决于机器了!( ...
随机推荐
- 适配器(Adapter)
Adapter:将一个Class的接口转换成另一个Class的接口,使原本因接口不兼容而不能合作的Class可以一起运作.主要有两种:迭代器适配器(Iterator Adpater)和容器适配器(Co ...
- HI3518E平台ISP调试环境搭建
海思的SDK提供了ISP调试的相关工具,降低了IPC的ISP调试的难度.初次搭建ISP调试环境,记录一下. SDK版本:Hi3518_MPP_V1.0.A.0 硬件平台:HI3518E_OV9732 ...
- java int and Integer
本文转自:https://www.cnblogs.com/guodongdidi/p/6953217.html int和Integer的区别 1.Integer是int的包装类,int则是java的一 ...
- ML(3)——线性回归
在统计学中,线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析.这种函数是一个或多个称为回归系数的模型参数的线性 ...
- mobx 知识点
antd+mobx 项目例子:https://github.com/cag2050/antd_mobx_demo 在 create-react-app 创建的项目中,使用 mobx:https://s ...
- sql语句实战
1,排名,自身连接,用count,去重用distinct 2,累加,和上面一样,自身连接,用sum 3,count函数不用group by只有一组
- python多线程、多进程相关知识
Queue Queue用于建立和操作队列,常和threading类一起用来建立一个简单的线程队列. 首先,队列有很多种,根据进出顺序来分类,可以分成 Queue.Queue(maxsize) FIFO ...
- django 保存中文到mysql 报错django.db.utils.DatabaseError: Incorrect string value: '\xE5\xBE\x88\xE7\x81\xB5
分析: 1.尝试在Python中对数据转码成utf8,'中文'.encode("utf-8"),还是报错 2.观察堆栈发现应该是操作mysql数据库的时候,将数据插入表里出错 所以 ...
- 负载均衡器 Ribbion
一.客户端负载均衡器 Ribbon 客户端向服务器如Eureka Server拉取已经注册的服务信息,然后根据负载均衡策略, 直接命中哪一台服务器发送请求. 整个过程在客户端完成,不需要服务器的参与. ...
- ulimit设置内存限制是否有效
如何使用ulimit限制物理内存 限制物理内存 $ ulimit -m 512000 经测试,无效. 限制物理内存不起作用,ulimit不支持限制物理内存,可见man ulimit手册 -m The ...