| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4430 人关注过本帖
标题:此帖为质疑讨论帖,知识碰撞帖,指导贴,由我回答某人问题被质疑开展开的
只看楼主 加入收藏
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
回复 30楼 自学的数学
char 有 CHAR_BIT 位,只是C语言规定 CHAR_BIT 必须大于等于 8。
现在9bits的不常见,但10bits、12bits、16bits的还挺多的。

signed char 是具符号的,unsigned char 是无符号。
但 char 是否具符号由实现定义,比如 gcc 中char默认就是无符号的。
C语言规定 char、signed char、unsigned char 是三种不同的类型。
收到的鲜花
  • 叶纤2020-03-20 21:25 送鲜花  6朵   附言:感谢补充新知识
2020-03-20 21:19
forever74
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:CC
等 级:版主
威 望:58
帖 子:1696
专家分:4295
注 册:2007-12-27
收藏
得分:0 
嗯,我来敲敲黑板。

上方讨论的是溢出,就是数据类型长度有限,当数值大到一定程度造成位数不够用的现象。
首先引经据典,C标准说过,(下面的“标准”是个名词,指C语言的规范,请大家脑补,给这个词拟人化一下)
    无符号整数的溢出(请注意,首先是溢出)结果是确定的,我就不多说了;
    有符号整数的溢出是未定义行为。这个就是标准自己的局限了(某种意义上)或者说正是标准不受局限的地方(在某'种意义上)。

那么,标准为什么这样说呢?因为标准的野心是想要C语言能运行在一切硬件平台上。
某些设计思路比较清奇的硬件平台可能会使用比较清奇的方式表达有符号整数溢出这件事,标准说我容忍你的清奇,我不表态(这就是未定义行为这个词在这个知识点上的含义)。

但是(某位腕儿说过,其实但是之前都是废话),
由于小F我见识有限,只见过不那么清奇的硬件,所以一般情况下有符号整数的溢出结果也是可预期的
它和无符号整数一样,最大值再加一会变成最小值。
也就是说signed char类型最大表示127,再走一步就变成-128。
一般的signed short如果是16位,它表示的最大就是32767,再前进就是-32768。
也就是说,在眼前常见的硬件上,占用n位二进制位的有符号整数,它能表示的最大值是2的n-1次方减1,再加1造成溢出,会绕回到负的2的n-1次方。

所以,溢出是一个定义性术语,绕回是一个描述性词汇,它俩不会对撞什么的。
那么最后,
需要使用有符号整数的时候使用有符号整数
需要使用无符号整数的时候使用无符号整数
无所谓的时候无所谓
收到的鲜花
  • 叶纤2020-03-20 21:40 送鲜花  6朵   附言:感谢补充新知识我喜欢回绕这词

对宇宙最严谨的描述应该就是宇宙其实是不严谨的
2020-03-20 21:35
forever74
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:CC
等 级:版主
威 望:58
帖 子:1696
专家分:4295
注 册:2007-12-27
收藏
得分:0 
标准之所以讲话很不爽利是因为它端着架子,很怕被打脸,因此凡是有可能有例外的地方它都不说个痛快话儿。
所以我们看到未定义行为、未指明行为 和 实现定义行为,要辩证地理解。

对宇宙最严谨的描述应该就是宇宙其实是不严谨的
2020-03-20 21:51
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
以下是引用forever74在2020-3-20 21:35:30的发言:
一般情况下有符号整数的溢出结果也是可预期的

并不这样,当然或许在汇编层面你说得对。
但既然C/C++规定了 具符号的溢出属于未定义行为,那C编译器就可以据此进行代码优化。
此贴是由 https://bbs.bccn.net/thread-500418-1-1.html 引发的,就拿他的代码举例,如果其代码中将无符号类型换成具符号类型的话,那么 clang 等编译器就会将 while(a>0) 替换成死循环。
clang为此作过解释,大体意思是:
既然具符号类型一开始大于0,那么自增后只能更大于零,不可能会变小;
如果说溢出,因为具符号类型的溢出是未定义行为,所以死循环也是符合标准规定的行为之一。
2020-03-20 23:38
forever74
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:CC
等 级:版主
威 望:58
帖 子:1696
专家分:4295
注 册:2007-12-27
收藏
得分:0 
我和标准风格不同。
我预防打脸的方式是“见识有限”和“一般情况下”。
而且“一般”也不是学术意义,而是某种口语环境下表达非特定的常见的意思。

对宇宙最严谨的描述应该就是宇宙其实是不严谨的
2020-03-20 23:46
d7se123
Rank: 2
等 级:论坛游民
帖 子:65
专家分:14
注 册:2020-3-13
收藏
得分:0 
回复 27楼 d7se123
谢谢老弟了  
2020-03-21 13:38
lidepeng1995
Rank: 2
等 级:禁止访问
帖 子:30
专家分:43
注 册:2018-7-8
收藏
得分:0 
回复 楼主 叶纤
我听说无符号类型效率好就用无符号进行加减运算,每次小的数减去大的数都不是正确结果,原来是无符号的陷阱啊
了解到了,溢出的话直接换更大的类型,楼主说的对在加减运算中确实容易出现不好的结果
2020-03-21 14:07
lidepeng1995
Rank: 2
等 级:禁止访问
帖 子:30
专家分:43
注 册:2018-7-8
收藏
得分:0 
那个争论的帖子我也看了,2楼应该关注的结果,说应该换更大的类型,
楼主回复的应该是那个帖子对于
避免使用无符号类型,因为使用无符号进行运算有可能会出现环绕和益处,就比如你第二个代码,如果益处就会进入环绕状态,也就是说最后是1-1=0,0不大于0为faulse,此时终止循环,楼主又说了把a定义为0,那就直接faulse,然后直接a-1为复数,此时进行了环绕为最大值

产生的提问
以下是引用下凡小仙男在2020-3-18 22:06:59的发言:

就是unsigned 少用吗 我今天看视频学到了这个就用了下哈哈哈
然后就有了楼主的回答吧?
2楼的回答对于溢出的话其实也没错,但是对于加减运算上出现负数的情况2楼应该也是清楚的只是没说出来
2020-03-21 14:21
快速回复:此帖为质疑讨论帖,知识碰撞帖,指导贴,由我回答某人问题被质疑开展开 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.031840 second(s), 12 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved