关于C的while循环不成立条件的发现?求解!!

GeekWay 2012-05-20 11:10:45
最近写C语言程序发现了几点问题,求高手指点!!
在很多关于C语言循环条件的书籍上都是这么说的:当值为真(非0)时, 执行循环体语句。当值为假(0)时退出循环。包括谭浩强的《C程序设计》和《C++ Primer》。但是最近重新研读C时,却发现了一些问题,具体见下面代码(当然,有一些时死循环):

#include"stdio.h"
int main()
{
while(0)
{
printf("while(0)的循环执行了。\n"); //很明显,这段不会执行!
}

//下面问题来了! 数值0的ASCII码是48(十进制),而使用ASCII码时却出现了问题,见下面:
int a='\x30';//数值0的ASCII码十六进制是:'\x30'
while(a)
{
printf("while(a)的循环执行了。\n"); //此段代码得到了执行!!!!!
}

//下面的问题更加离奇,使用‘\0’作为循环条件时不会执行循环程序
while('\0')
{
printf("while('\0')的循环执行了。"); //这个循环也没有得到执行
}

printf("执行了循环外的程序!\n");

return 0;
}

我在VC6.0和C_Free这两个编译器上都得到了同样的结果。
既然这样,上面的那条结论就不正确了,还网友帮我解答一下吧,万分感谢!!!
...全文
865 53 打赏 收藏 转发到动态 举报
写回复
用AI写文章
53 条回复
切换为时间正序
请发表友善的回复…
发表回复
feng2294 2012-06-11
  • 打赏
  • 举报
回复
不了解..看不懂
AnYidan 2012-05-24
  • 打赏
  • 举报
回复
(nul) 0 0000 0x00 这就是数值 0 的 ASCII 码

ASCII 码 只占用 8-BIT
GeekWay 2012-05-24
  • 打赏
  • 举报
回复
[Quote=引用 49 楼 的回复:]

大部分人能这么耐心的和楼主交流,我还是感到很欣慰的。楼主不过是钻了一下牛角尖,一下子没反应过来,这么多热心人耐心解说,让我感到生活还是有希望的。
[/Quote]

理解万岁,LZ好久没碰C语言了,在这个小问题上犯2了。谢谢各位网友的悉心指点,让我拨开了迷雾(虽然是小问题,可当时真是疑惑的要死),谢谢大家!!!
GeekWay 2012-05-24
  • 打赏
  • 举报
回复
[Quote=引用 49 楼 的回复:]

大部分人能这么耐心的和楼主交流,我还是感到很欣慰的。楼主不过是钻了一下牛角尖,一下子没反应过来,这么多热心人耐心解说,让我感到生活还是有希望的。
[/Quote]

理解万岁,LZ好久没碰C语言了,在这个小问题上犯2了。谢谢各位网友的悉心指点,让我拨开了迷雾(虽然是小问题,可当时真是疑惑的要死),谢谢大家!!!
宋哥 2012-05-23
  • 打赏
  • 举报
回复
大部分人能这么耐心的和楼主交流,我还是感到很欣慰的。楼主不过是钻了一下牛角尖,一下子没反应过来,这么多热心人耐心解说,让我感到生活还是有希望的。
LATERBOY110 2012-05-23
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 nikannishishui 的回复:]
神奇帖啊,楼主这种智商学习编程是在侮辱整个编程界,强烈建议楼猪转学业,你适合学习文学,或者去大街上摆摊,这里不适合你。
[/Quote]

大鸟 在说话的时候动下你的脑子 能这么说人的嘛 谁没有过不明白的时候
jiligululalala 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 的回复:]

你好,你的回复对我帮助很大!
我想请教一下,我在while(__)条件里面写上数值:0 或 字符'\0' 都能使循环退出,但两者的ASCII码并不相同(数值0的ASCII码是48,'\0'的ASCII码是0),说明编译器不是通过ASCII码判定循环条件的,我上面的while(a)即while('\x30') 也验证了这一点。老谭的那句“当值为真(非0)时, 执行循环体语句,当为假(0)是退出循环”是不是说的过于笼统啊?C是怎么实现循环退出的啊?(抱歉,我用C++和Java太久了,C完全抛弃了)

[/Quote]


没必要把问题弄的那么复杂。

while(0) 这里是一个数字0,while判断到0,结束循环。

int a='\x30';
while (a) 这里a是一个变量,且已经赋值,其值是48。while判断a不是0,所以循环继续。


int a='\0';
while (a) 这里a是一个变量,且已经赋值,其值是0,while判断a是0,所以循环结束。

说到底,还是 0 '0' '\0'这三者的区别。弄个printf打印一下,什么问题都解决了。

Athenacle_ 2012-05-22
  • 打赏
  • 举报
回复
不好意思,二进制是:0011 0000的东西,是字符0,不是数字0
GeekWay 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 的回复:]

LZ去试试'\0'这个字符用二进制表示是多少?

诶。。LZ问这样的问题,别说编译原理,先去补习下汇编把
[/Quote]

那么数值0的二进制是:0011 0000 ,也不是0啊,求教!!可不可以给解释下“当值为真(非0)时, 执行循环体语句。当值为假(0)时退出循环。”的原理?谢谢!
Athenacle_ 2012-05-22
  • 打赏
  • 举报
回复
LZ去试试'\0'这个字符用二进制表示是多少?

诶。。LZ问这样的问题,别说编译原理,先去补习下汇编把
子谋 2012-05-22
  • 打赏
  • 举报
回复
大哥,所谓0和非0都是针对数值来说的……
对于C语言,先把一切的种种,char也好,指针也好,结构体也好,任何类型先变成数值,然后再判断所谓0和非0……
prohibit 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]
int型和char型是相通的,
printf("a=%d\n",a);执行后的结果确实是48,因为你按照int类型输出的,但是代码改为:
int a='\x30'; //或char a = '\30';
printf("a=%c\n",a);
输出的结果的确是:0
难道编译器在经过表达式运算后自动转化为整型?我没学过《编译原理》,这边不大懂!!
[/Quote]
int a='\x30'; //或char a = '\30';
printf("a=%c\n",a); // 这里打印的是字符,assic中\x30是48,所以显示的是0,但值依然是48

Dec Hex Char
48  30  0

如果你要看a是不是0,那就直接if (a == 0)来判断,别转成char或其他进制等等的来肉眼看~~
GeekWay 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 的回复:]

LZ既然看过了书了,那我拿书上的原话跟你讲。。< C primer plus > 121页,讲到while循环,里面的原话是 “请注意关系表达式也可以用于字符的比较。进行比较时使用的是机器的字符代码(我们假定为ASCII)
" 也就是说,'0'比较是时候其实是48,而不是用字符做比较
[/Quote]

你好,你的回复对我帮助很大!
我想请教一下,我在while(__)条件里面写上数值:0 或 字符'\0' 都能使循环退出,但两者的ASCII码并不相同(数值0的ASCII码是48,'\0'的ASCII码是0),说明编译器不是通过ASCII码判定循环条件的,我上面的while(a)即while('\x30') 也验证了这一点。老谭的那句“当值为真(非0)时, 执行循环体语句,当为假(0)是退出循环”是不是说的过于笼统啊?C是怎么实现循环退出的啊?(抱歉,我用C++和Java太久了,C完全抛弃了)
GeekWay 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

int a='\x30';//数值0的ASCII码十六进制是:'\x30'
貌似这个最后'a‘值不是'0'吧。
我觉得你自己在语句后面加一个
printf("a=%d\n",a);
就可以明白自己错在哪里了。
你的问题不是出现在while循环体语句上面,而是在转义字符上。
好好研究下转义字符吧。
[/Quote]
int型和char型是相通的,
printf("a=%d\n",a);执行后的结果确实是48,因为你按照int类型输出的,但是代码改为:
int a='\x30'; //或char a = '\30';
printf("a=%c\n",a);
输出的结果的确是:0
难道编译器在经过表达式运算后自动转化为整型?我没学过《编译原理》,这边不大懂!!

GeekWay 2012-05-22
  • 打赏
  • 举报
回复
=================终结贴===================

谢谢各位网友的指点,现在LZ终于被点醒了。
当时翻看谭后面的ASCII附录,突然疑由心生,接着就一发不可收拾了,竟然在编译器验证后都不敢相信,确实我把数值0和字符'0'和'\0'搞混了。
现在总结一下吧:
数值0是没有ASCII码的,根据编译器的不同,int 类型的字节数也不尽相同,TURBO C上int占2字节,VC和C_Free占4个字节。依4字节为例,数值0在内存存放的是:0000 0000,0000 0000,0000 0000 ,0000 0000 ,
而字符'\0'是一个char类型,占1个字节,在内存中存放的是:0000 0000。所以会出现while(0)和while(\0)得到相同结果的情况。
字符'0'的ASCII码是:0011 0000,放入while()后自然不会得到0退出循环。

还有说的不全的还请大家指点,说的不对的地方请大家抨击指正,谢谢大家!!!准备明早结贴!!!!!
GeekWay 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 的回复:]

引用 18 楼 的回复:

引用 9 楼 的回复:

神奇帖啊,楼主这种智商学习编程是在侮辱整个编程界,强烈建议楼猪转学业,你适合学习文学,或者去大街上摆摊,这里不适合你。


9楼严重了,说到适不适合编程,楼主有多年编程经验,还曾获得过全国软件设计大赛的二等奖,不敢称自己是编程高手,只能说自己入门了吧。向9楼说的“侮辱整个编程界”,有点严重了。这里楼主只是质疑一些经典书籍中的……
[/Quote]

嘿嘿,当时考的是C++,我只考虑了C++的bool类型,对这个C的细节完全忽略了!唉,承认自己太二了,O(∩_∩)O~
赵4老师 2012-05-22
  • 打赏
  • 举报
回复
对电脑而言只有二进制字节,对人脑才有字符、数字、零、……
nanjingnew4 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 的回复:]
引用 23 楼 的回复:

LZ既然看过了书了,那我拿书上的原话跟你讲。。< C primer plus > 121页,讲到while循环,里面的原话是 “请注意关系表达式也可以用于字符的比较。进行比较时使用的是机器的字符代码(我们假定为ASCII)
" 也就是说,'0'比较是时候其实是48,而不是用字符做比较


你好,你的回复对我帮助很大!
我想请教一下,我在while(__)条……
[/Quote]
只是假定为ascii码,他这里说的就是数值0,while循环中0为假,为0为真,都讲的是数值
jiligululalala 2012-05-22
  • 打赏
  • 举报
回复
while (0)
while (1)
while (2)
while (3)
while (!1)
while (!2)
while (!3)

if (0)
if (1)
if (2)
if (3)
if (!0)
if (!1)
if (!2)
if (!3)

有时间辩论,还不如动手写几行简单的代码,看看这些括号里面的表达式的值是多少,但愿这个能帮助楼主理解。
a128vs 2012-05-22
  • 打赏
  • 举报
回复
嘿 不知道底层真的好无奈,我得回头再学
加载更多回复(33)

70,012

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧