为啥这个循环在c中运行无限次?
Posted
技术标签:
【中文标题】为啥这个循环在c中运行无限次?【英文标题】:why this loop is running infinite times in c?为什么这个循环在c中运行无限次? 【发布时间】:2015-03-27 03:58:00 【问题描述】:我只是在 C 编程中试验一段代码。并开始知道一个奇怪的行为。 嗯...由于我不是C语言专家,所以我不知道它是奇怪还是正常。
基本上我的问题都是关于以下两行代码之间的区别:-
char a = 'h'; // here variable a is not an array of "char"
和
char a = 'hi'; //here variable a is not an array of "char" as well (i don't know if compiler assumes it as an array or not but , at least i didn't declared it that way )
我使用了以下代码
第一:-
char a =0;
for(;a<'hi';a++)
printf("%d= hello world \n",a);
秒:-
char a;
for(a='h';a<'hi';a++)
printf("%d= hello world \n",a);
上面提到的两个循环都会永远运行,
谁能告诉我为什么会这样?
我可能遗漏了一个非常基本的编程概念。请帮帮我
【问题讨论】:
解释你是如何等待无限长的时间的:-)'hi'
是错误的,2 个字符表示它是一个字符串,需要双引号,"hi"
衰减为一个指针。正确的声明是 const char * a = "hi";
或 char a[] = "hi"
顺便说一句,如果您编译时包含所有警告和调试信息(例如 gcc -Wall -Wextra -g
),编译器会警告您(然后您可以使用 gdb
调试器)
相信编译器。如果它警告你你的代码是错误的。并阅读undefined behavior
Multichar 常量是实现定义的。不同的编译器(或构建平台目标)可以产生不同的值。您通常不能依赖它,并且大多数编译器都会警告您。你总是可以避免使用它们,所以不要。 'foo'
和 "foo"
是完全不同的东西。
【参考方案1】:
在 C 中(与某些 cmets 中引用的 C++ 相对),字符文字 总是 具有类型 int
。无论是普通的单字符文字,例如“c”,还是多字符文字,例如“hi”,都没有关系。它始终具有int
类型,需要至少保存 16 位。 char
恰好包含一个字节。
当比较不同类型的整数值时,整数提升规则开始起作用,较小的整数值被提升为较大的整数值。
这就是为什么a < 'hi'
只能是1
(“真”)。即使提升为int
类型,变量a
也永远不能容纳大于MAX_CHAR
的任何内容。但是多字符文字'hi'
是一个int
,其值大于在您的编译器的实现中。
a < m
能够成功的原因是,当声明m
时,你用'hi'
初始化它,它被转换为char
类型,它确实有机会比较不小于另一个@ 987654335@.
【讨论】:
第一段之后的东西..完全超出了我的想象。 :) 我的意思是无法理解整数提升规则。没有冒犯。 @DemonSOCKET 那么你应该阅读更多关于它的信息。不然以后会痛的。 @DemonSOCKET:描述中到底有什么不清楚的地方?你检查过标准吗?【参考方案2】:这是因为'hi'
的类型为int
而不是char
。它也解析为值 26729。但循环变量很可能(假设 char
是 1 字节类型,字节有 8 位)受 127 的限制,然后溢出。
请注意:
char a =0;
char m = 'hi';
for(; a < m; a++)
printf("%d= hello world \n",a);
会起作用,因为'hi'
将被强制转换为 char (105)。
'hi'
是一个多字符文字。这在编程中并不常见,它是“鲜为人知”的 C 特性,已成为 C99 标准的一部分。更多关于他们的信息:http://zipcon.net/~swhite/docs/computers/languages/c_multi-char_const.html
【讨论】:
或许值得一提的是,它甚至有一个专有名称 - 多字符文字 我怎样才能找到'hi'的值。或根据 Mints97 任何“多字符文字” 多字符文字的整数值对我来说看起来很狡猾,但是:C99 => §6.4.4.4.10: "包含多个字符的整数字符常量的值(例如,'ab'),[...] 是实现定义的。”,因此这里可能存在一些未定义的行为 @DemonSOCKET:它是实现定义的。正如 Sergey 解释的那样,一些编译器将符号的 ASCII 值组合在一个多字符文字中,而一些编译器只取文字的最后一个字符。要弄清楚你的情况是什么值,只需将其作为数字输出到标准输出 =) 换句话说,避免它们。如果您真的想组合两个文本字符,请以您知道结果的方式进行操作:int a = ('h'<<8)+'i';
。以上是关于为啥这个循环在c中运行无限次?的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript+css实现转向灯双闪animationanimation-iteration-countkeyframesinfinite循环动画动画执行无限次