c语言,未定义行为总结.docxVIP

  1. 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
c语言,未定义行为总结   C语言的初学者经常会问一些貌似“专业”的问题,比如   #include   main()   {   inti=5;   intj=++i+++i+++i;   printf(%d\n,j);   system(pause);   }   这样的问题实在不需要多做考虑,而且应该在实际编程实践中尽量避免。因为它们几乎都是“未指明的行为”或“由实现定义的行为”。另一方面,程序的错误或Bugs,通常是由于“未定义的行为”。   C++Primer第四版中的解释:   使用了未定义行为的程序都是错误的,即使程序能够运行,也只是巧合。   未定义行为源于编译器不能检测到的程序错误或太麻烦以至无法检测的错误。   不幸的是,含有未定义行为的程序在有些环境或编译器中可以正确执行,但并不能保证同一程序在不同编译器中甚至在当前编译器的后继版本中会继续正确运行,也不能保证程序在一组输入上可以正确运行且在另一组输入上也能正确运行。   程序不应该依赖未定义行为。   C语言缺陷与陷阱   C语言像一把雕刻刀,锋利,并且在技师手中非常有用。和任何锋利的工具一样,C会伤到那些不能掌握它的人。本文介绍C语言伤害粗心的人的方法,以及如何避免伤害。   第一部分研究了当程序被划分为记号时会发生的问题。第二部分继续研究了当程序的记号被编译器组合为声明、表达式和语句时会出现的问题。第三部分研究了由多个部分组成、分别编译并绑定到一起的C程序。第四部分处理了概念上的误解:当一个程序具体执行时会发生的事情。第五部分研究了我们的程序和它们所使用的常用库之间的关系。在第六部分中,我们注意到了我们所写的程序也许并不是我们所运行的程序;预处理器将首先运行。最后,第七部分讨论了可移植性问题:一个能在一个实现中运行的程序无法在另一个实现中运行的原因。   词法分析器:检查组成程序的字符序列,并将它们划分为记号一个记号是一个由一个或多个字符构成的序列,它在语言被编译时具有一个统一的意义。   C程序被两次划分为记号,首先是预处理器读取程序,它必须对程序进行记号划分以发现标识宏的标识符。通过对每个宏进行求值来替换宏调用,最后,经过宏替换的程序又被汇集成字符流送给编译器。编译器再第二次将这个流划分为记号。   =不是==:   C语言则是用=表示赋值而用==表示比较。这是因为赋值的频率要高于比较,因此为其分配更短的符号。C还将赋值视为一个运算符,因此可以很容易地写出多重赋值,并且可以将赋值嵌入到一个大的表达式中。   和|不是和||   多字符记号   C语言参考手册说明了如何决定:“如果输入流到一个给定的字符串为止已经被识别为记号,则应该包含下一个字符以组成能够构成记号的最长的字符串”“最长子串原则”   例外   组合赋值运算符如+=实际上是两个记号。因此,   a+/*strange*/=1   和   a+=1   是一个意思。看起来像一个单独的记号而实际上是多个记号的只有这一个特例。特别地,p-a   是不合法的。它和   p-a   不是同义词。   另一方面,有些老式编译器还是将=+视为一个单独的记号并且和+=是同义词。   字符串和字符   包围在单引号中的一个字符只是编写整数的另一种方法。这个整数是给定的字符在实现的对照序列中的一个对应的值。而一个包围在双引号中的字符串,只是编写一个有双引号之间的字符和一个附加的二进制值为零的字符所初始化的一个无名数组的指针的一种简短方法。   使用一个指针来代替一个整数通常会得到一个警告消息,使用双引号来代替单引号也会得到一个警告消息。但对于不检查参数类型的编译器却除外。   由于一个整数通常足够大,以至于能够放下多个字符,一些C编译器允许在一个字符常量中存放多个字符。这意味着用yes代替yes将不会被发现。后者意味着“分别包含y、e、s和一个空字符的四个连续存储器区域中的第一个的地址”,而前者意味着“在一些实现定义的样式中表示由字符y、e、s联合构成的一个整数”。这两者之间的任何一致性都纯属巧合。   2句法缺陷   理解这些记号是如何构成声明、表达式、语句和程序的。   理解声明   每个C变量声明都具有两个部分:一个类型和一组具有特定格式的、期望用来对该类型求值的表达式。float*g(),(*h)();   表示*g()和(*h)()都是float表达式。由于()比*绑定得更紧密,*g()和*(g())表示同样的东西:g是一个返回指float指针的函数,而h是一个指向返回float的函数的指针。   当我们知道如何声明一个给定类型的变量以后,就能够很容易地写出一个类型的模型:只要删除变量名和分号并将所有的东西包围在一对圆括号中即可。   float*g();   声明g是一个返回float指

文档评论(0)

mmrs369 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档