打印

一个C语言问题,大家都遇到过吧?

[复制链接]
2488|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
幸福至上|  楼主 | 2015-9-14 16:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是一个关于无符号类型数的负数问题,来看个实际例子,比较好说明一点:
void example(void)
{
     unsigned char a=5;

    a-=7;//////a

     while(a)
     {
        a-=9;//////b
     }
}
1:a处执行完毕后,a的数值是多少? 2:会执行到b处吗? 3:该子函数能正常结束吗?
我也是在实际编程时,偶然使用一个算法,遇到这个问题,虽然糊里糊涂地调试通过了,但并不很明白其中原因,所以希望借此仔细研究下这个问题,以免下次再入此坑。
问题可能很简单,但我着实还没搞明白,所以在自己查资料的同时,也想发上来,让大家一起看下,讨论下这个C语言问题,说不定又会有新的收获 ;)

相关帖子

沙发
nethopper| | 2015-9-14 16:39 | 只看该作者
1. 按无符号数看的话是254,有符号数看的话是-2。
2. 会滴。
3. 能。就算总错过零点,最多转9圈总能撞上0吧。(只说原理,我没计算哈)

使用特权

评论回复
板凳
nethopper| | 2015-9-14 16:55 | 只看该作者
转5圈就出了,有点像小学奥数题

使用特权

评论回复
地板
rfvdfg| | 2015-9-14 17:09 | 只看该作者
本帖最后由 rfvdfg 于 2015-9-14 17:10 编辑

会执行到B处,无符号char,5-7 = 254 了

254/9 = 28 圈

使用特权

评论回复
5
nethopper| | 2015-9-14 17:24 | 只看该作者
我上面说的5圈,是指a的数值在256~0之间打转的圈数,每转的循环次数并不一定相同,其中有三转每转循环28次,另两转每转循环29次,共循环142次。

使用特权

评论回复
6
幸福至上|  楼主 | 2015-9-14 18:08 | 只看该作者
nethopper 发表于 2015-9-14 16:39
1. 按无符号数看的话是254,有符号数看的话是-2。
2. 会滴。
3. 能。就算总错过零点,最多转9圈总能撞上0吧 ...

你的意思是,转到正好a-=9,有一次正好使a=0就退出了,是这样吗?

使用特权

评论回复
7
nethopper| | 2015-9-14 18:10 | 只看该作者
幸福至上 发表于 2015-9-14 18:08
你的意思是,转到正好a-=9,有一次正好使a=0就退出了,是这样吗?

是这样

使用特权

评论回复
8
幸福至上|  楼主 | 2015-9-14 18:17 | 只看该作者
rfvdfg 发表于 2015-9-14 17:09
会执行到B处,无符号char,5-7 = 254 了

254/9 = 28 圈

254/9=28.2222...不能正好为0跳出来吧?

使用特权

评论回复
9
幸福至上|  楼主 | 2015-9-14 18:21 | 只看该作者

那如果定义变量a为: signed char a=5,这样就会直接跳过while()循环吗?

使用特权

评论回复
10
幸福至上|  楼主 | 2015-9-14 18:26 | 只看该作者
nethopper 发表于 2015-9-14 17:24
我上面说的5圈,是指a的数值在256~0之间打转的圈数,每转的循环次数并不一定相同,其中有三转每转循环28次 ...

实测确实在while()中跑了142次。。。

使用特权

评论回复
11
nethopper| | 2015-9-14 18:37 | 只看该作者
幸福至上 发表于 2015-9-14 18:21
那如果定义变量a为: signed char a=5,这样就会直接跳过while()循环吗?

只要a不为零都会循环。

使用特权

评论回复
12
nethopper| | 2015-9-14 18:39 | 只看该作者
幸福至上 发表于 2015-9-14 18:26
实测确实在while()中跑了142次。。。

哈哈,俺小学奥数是过关了滴

使用特权

评论回复
13
幸福至上|  楼主 | 2015-9-14 18:50 | 只看该作者
nethopper 发表于 2015-9-14 18:39
哈哈,俺小学奥数是过关了滴

;) 实际发现这是一个关于while()循环何时为真的问题...

使用特权

评论回复
14
zhuyjgh| | 2015-9-14 19:39 | 只看该作者
nethopper 发表于 2015-9-14 16:55
转5圈就出了,有点像小学奥数题

2 6 10 14 18  是这样推算出来的么??还是有其他的办法??比较好奇啊~~

使用特权

评论回复
15
nethopper| | 2015-9-14 21:11 | 只看该作者
zhuyjgh 发表于 2015-9-14 19:39
2 6 10 14 18  是这样推算出来的么??还是有其他的办法??比较好奇啊~~

初始值是254,a在0~255之间打转,每打转一次加256,看哪次正好能被9整除,所以退出循环的条件变为(254 + N x 256) / 9 为整数(而无余数),其中N是a在0~255之间打转的次数。

N=0,值为28余2;
N=1,值为56余6;
N=2,值为85余1;
N=3,值为113余5;
N=4,值为142余0;

所以5圈,总循环次数为:142

使用特权

评论回复
16
幸福至上|  楼主 | 2015-9-14 21:17 | 只看该作者
nethopper 发表于 2015-9-14 21:11
初始值是254,a在0~255之间打转,每打转一次加256,看哪次正好能被9整除,所以退出循环的条件变为(254 +  ...

好吧。。。你赢了啥,都这么算了。。。

使用特权

评论回复
17
zhuyjgh| | 2015-9-14 21:22 | 只看该作者
nethopper 发表于 2015-9-14 21:11
初始值是254,a在0~255之间打转,每打转一次加256,看哪次正好能被9整除,所以退出循环的条件变为(254 +  ...

额,,好,,这个思路清晰。。

使用特权

评论回复
18
小鬼1030| | 2015-9-14 21:30 | 只看该作者
首先会变成254,然后会不断的减9循环,直至见到0

使用特权

评论回复
19
wangheng1888| | 2015-9-14 21:39 | 只看该作者
nethopper 发表于 2015-9-14 21:11
初始值是254,a在0~255之间打转,每打转一次加256,看哪次正好能被9整除,所以退出循环的条件变为(254 +  ...

这个不错一看明了!

使用特权

评论回复
20
le062| | 2015-9-14 22:15 | 只看该作者
孔乙己你好,孔乙己再见

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:重庆电子交流圈:521107487,欢迎各位工程师朋友们加入,一起交流讨论,互动分享,共同进步。

38

主题

854

帖子

10

粉丝