标题：品悟C——抛弃C程序设计中的谬误与恶习
图书信息
作者：薛非 
图书详细信息：ISBN：9787302296263定价：69元印次：1-1装帧：平装印刷日期：2012-8-31
图书简介
这是迄今为止国内仅有的一部全面且集中地讨论C程序设计中常见错误的书籍。其主旨在于帮助读者从错误中更准确地理解C语言，并在实践中更好地运用C语言。全书分为上下两部：上部“形而下学”讨论C代码中常见的错误和编程恶习；下部“形而上学”讨论的是对C语言本身认识方面的常见误区。这些问题特别具有普遍性，很多错误不仅仅存在于初学者之中，即使是职业程序员多半也会在本书中找到自己的错误。因此，对于任何想纠正自己对C语言的错误认识以及想不断提高C语言水平的读者来说，本书都提供了一种独到且重要的视角，是一本不容错过的、具有重要参考价值的技术资料。本书并非那种长篇大论环环相扣的书籍，它的各个主题独立成篇，使人阅读起来轻松愉快。读这本书并不需要正襟危坐在书房里，它可以随时随地地拿过来翻阅。本书可作为各高校C语言或相关课程的教学参考书，也适合那些具有一定经验的C语言程序员阅读使用。
图书前言
编者序——敢于向权威挑战经常听到我的作者朋友说类似这样的话：“看我的代码，多帅气！”何谓帅气、漂亮的代码？在我看来，先不谈代码丑俊，首先代码必须没有残疾。在健康的代码基础上，才能谈网络间流传的各种称号：漂亮代码、优质代码、帅气代码、性感代码……这就是本书要讲的内容——摒弃一些错误的观念，重新认识C语言的严谨与华丽。计算机语言是人类操控计算机硬件的主要手段，是语言创造者智慧的浓缩。计算机语言在中国的普及，是伴随着中国经济腾飞的这几十年。无数中国的程序员伴随着很多经典教材顺利入门并成长了起来，随着互联网的发展，更多的朋友在网上发表自己的看法，所以互联网也成为了大家获取编程技术的重要渠道。但是，金无足赤，随着C语言标准的不断完善，C开发理念的不断进步，市面上的一些教材和网上一些说法确实存在一些值得商榷的问题，或者谬误，因为这些资料传播甚广，有些反而成为了“标准”，这种现象有时候可能会误导初学者，让初学者无法从一开始就建立相对准确的开发观念。本书就是这样一本敢于向“权威”挑战的书，通过作者多年的积累，以及众多热心网友的鼎力支持，对一些C语言中经常出现的问题进行讨论。在中国的教育体制下，不可否认，很多创造力被限制甚至扼杀，很多路被强制标注为正确途径，很多人的学习兴趣在一开始就被磨灭……。但是很高兴能出现这么一本书，在阅读过程中，可以体会一众先锋程序员对开发观念的重视，对细节的精益求精，对逻辑的反复推敲，甚至上升到——对真理的求索。我通常拿到一本书，会先浏览一下，把我认为重要的文字用特殊形式标出来，比如“提示”、“注意”、“TIPS”之类的样式以及文字加粗、代码加黑之类的重点标注，但是本书我在做出努力之后，发现无法进行这样的处理，因为似乎每句话都是重点，每段代码都是精心挑选的，无论是正确代码还是错误代码。最后一点不得不提一下，作者的文笔非常犀利，对一些问题的批判毫不留情，可能是作者本人以及相关参与编写的网友受到过太多问题资料的影响，以至于走了不少弯路，所以面对问题资料，个别时候会流露出来一种愤青一般的愤怒。这可以理解，而且我在编辑加工过程中也尽量保持了文风，但是还是希望作者和所有读者做一名淡定的程序员。如果本书冒犯了某些朋友，请不要大动肝火，可以发邮件与作者讨论，毕竟从一个角度看问题，存在片面的可能性。大家讨论技术，以代码会友。
权威之所以是权威，必然有其可取之处，对于权威，我们除了要有挑战的勇气，更多的是要理性的尊重，毕竟“权威”带领太多人进入C语言门槛。没有BUG的代码是不存在，同样没有问题的资料也是不存在的，希望大家在学习过程中，多思考，多交流，早日树立端正的开发思路。在此感谢包括作者在内的热心人，有监督才会有活力，有挑战才会有发展！前言
这是一本什么样的书这是一本关于C 程序设计常见错误的书。书中详尽地剖析、讨论了学习或使用C 语言过程中常见的一些错误观念和错误实践。目的是帮助读者更准确地理解并运用C 语言。为什么要写这样一本书因为错误①与程序设计一向如影随形，密不可分。只要编写程序，就无法避免错误。这是一条铁律。无论是初出茅庐的新手还是经验丰富的老手，无一例外。从某种意义上来说，软件业的主要工作有三项：制造错误、改正错误和掩饰错误。因此不深入了解和认识错误就不可能真正懂得编程。孔子说：“未知生，焉知死？”程序设计也是这个道理，不懂得错误就不可能真正理解程序设计语言的要点及编程的真谛。实践表明，人们从错误中学习到的东西往往比从正确中学到的多得多。这就是人们常说的“吃一堑，长一智”。事实上每个程序员的成长历程都是一部不断认识错误并予以改正的纠错史。每一个优秀的程序员无一不是从无数的错误中脱颖而出的，并且始终要与错误进行不懈地斗争。闪光的思想一向少不得经历错误的磨砺。从这个角度来看，对程序设计中的错误进行讨论比那些一本正经地正确叙述更有助于程序设计人员水平的提高，本书的目的就在于此。然而尽管市场上C语言的书籍多得可以车载斗量，但遗憾的是几乎鲜有专门论述C程序设计中错误的书籍，除了Koenig所著的《C陷阱与缺陷》。不过我觉得作者Koenig先生“阐之未尽，我有我的看法”。实际上Koenig先生并不了解中国国情，他不知道程序设计中的错误其实分为两种，一种是错误，另一种是中国式错误。一句话，他根本无法想象我们是用质量何等奇特的教科书、用何等落后的方式学习C编程。因此他的书只提到了普通的一般性错误，而对形形色色的具有中国特色的错误却只字未提。这是一个巨大的、需要填补的空白（我不知道这算不算学术空白，从某种意义上来说这更像是清除技术污染）。这项工作目前来看还没有人做。既然古代的圣贤曾经教诲过我们应该“当仁不让”，所以现在只好由本书来勉为其难了。错误是怎样“炼”成的众所周知，所谓编程在本质上无非是用特定的形式语言向计算机描述一个问题的解①错误有很多文雅含蓄或直截了当的称呼，比如：缺点(defect)，偏差(variance)，故障(fault)，失败(failure)，问题(problem)，矛盾(inconsistency)，错误(error)，特殊(feature)，事件(incident)，缺陷(bug)，异常(anomaly)，不良反应(idiosyncrast)，崩溃(breakdown)……，不一而足。本书后面通称为错误或BUG。
决方法。在此之前，对这种语言的学习也是一个必不可少的环节。在整个过程中的一系列环节的任何一个环节上都可能会出现错误。首先，语言的学习过程中会产生许多错误。这些错误不仅是因为学习者自身的原因，同时也是由于教科书方面的原因。许多虔诚的学习者内心的潜意识里会以为教科书不会有什么错误，他们一向跪在教科书上学习，遇到错误时只是不断地检讨自己。在这个连婴儿奶粉都可能含有三聚氰胺的社会，怀有这种念头实在是too.naive了。没有任何理由指望你的教科书比婴儿奶粉更纯净。教科书同样可能有错，这种“水源”的污染才是最严重的污染。在这种情况下，只查找自身出错的原因是不可能解决问题的。这种先入为主的错误非常难以纠正，而且其影响往往也最为深远。例如，很多人在成为职业程序员之后也还不清楚a+=a‐=a*a.这个表达式是不正确的。对语言不够熟悉是初学者犯错误的另一个主要原因。通常表现为代码里不是缺点儿什么就是多点儿什么。这种错误是一种最初级的错误，连编译器能够指出，因而比较容易得到纠正，所以多半不足为虑。学习一种语言，本质上就是为了学习一种新的思维方式。将平时不严谨的自然语言思维习惯带入程序经常会导致对程序设计语言的误解，例如把“x不等于1或2”错误地表达为x!=1||x!=2甚至我们所熟悉的严谨的数学语言，由于语境发生了变化，也会在程序中带来错误。例如，很多人都犯过把“==”（“等于”）写成数学中的“=”（“赋值”，在数学领域表示“等于”）这种错误。这种错误一般需要通过长期的自觉训练来纠正。往往被初学者所忽视的是不良编程习惯的问题，他们一心只想着写正确的代码，而从不考虑如何正确地写出正确的代码。这往往会导致许多低级错误一犯再犯，比如一再出现括号不成对这样的问题。缺乏良好的编程习惯是写不好程序的，任何一个工人都懂得：良好的产品质量需要由合理的工艺来保证。不懂得正确地编写程序就几乎不可能写出正确的程序。初学者忽视不良习惯的另一个主要原因是，这些编程陋习有时并不能在短期内显示出其恶果，比如“int.a,b,c;”这种烂得不能再烂的变量名。实际上良好编程习惯的意义不仅在于避免错误，还在于它意味着少犯错误，或者在出现错误时很容易检查到并修正，这些长远的利益在短时间内一般是体会不到的。良好的习惯要靠自觉培养，但是如果教科书没告诉你这些，那是教科书的问题。因为初学者不可能在短时间内完全靠自己的悟性领会前人几十年积累下来的编程规范方面的经验。顺便说一句，有些教科书的代码风格本身就极滥无比，对初学者误导很大。仅仅熟悉语言元素对于编程来说是远远不够的，因为每一个程序的目标都是为了解决问题。而从问题到程序要经历问题的提出、问题的分析到问题的解决，最后落实为代码，在这一过程中每一个步骤都可能会出现错误。正确地提出问题是解决问题的先决条件，错误的问题是不可能解决的。例如，要求“输出1~n*n的自然数构成的魔方阵”就是一个错误的问题，因为2阶的魔方阵根本不存在。求解这样的问题，可以说是未解先错。问题提出模糊不清的要求也是一种错误，例如“有三个数a、b、c，要求按大小顺序把它们输出”，这里的三个数究竟是什么数，是模糊不清的，在不同的情况下代码截然不同。要求应该明确。要求不清是提出者的错误，但擅自猜测问题的要求则是程序员的错误。编写求解错误问题或不严谨问题的程序有害无益，而且贻害无穷，这会使程序员在不知不觉中丧失必要的职业严谨，对错误的需求渐渐变得麻木不仁。要知道，在真实的开发中，因为软件需求错误而导致的软件错误占到错误总数的一半以上，而且那些错误的需求往往不那么清楚明显、容易察觉。不具备审视问题或要求是否合理的习惯和能力，在真正的软件开发中就如同盲人骑瞎马，不可能不掉到沟里。初学者中很少有人意识到问题本身可能就是错误的。很多初学者常常不管三七二十一地解决错误的问题。这对他们的逻辑思维能力是一种巨大的慢性戕害。即使正确地提出了问题，也还可能被程序设计者所误解。错误地理解问题的要求，同样是错误产生的一个重要原因。分析问题的过程中最容易产生逻辑错误，或者对问题分析得不全面导致的顾此失彼。这种不全面的逻辑漏洞往往比完全的逻辑错误更难发现，因为这时程序的运行有可能会“显得”是正确的。即使没有前面提到的那些错误，距离写出优秀的代码还有很长的路。写代码和写文章一样，需要精心地进行布局谋篇，用术语来说就是进行设计。设计不仅包括算法设计还包括对数据结构的设计。在“算法——程序的灵魂”这种片面观点的误导下，很多人轻视数据结构的设计，冥思苦想所谓的算法。实际上算法和数据结构是密不可分的，那些艰深晦涩的糟糕算法，大多是因为垃圾的数据结构设计。有些人写程序毫无设计意识，上来就开始匆忙写代码，东一榔头西一棒槌，写到哪算哪，写出的代码笨拙无比、僵硬造作、逻辑混乱、啰唆重复或者效率低下。这样的代码即使能输出结果，也是不合格的丑陋代码。难道程序长得丑陋也是一种错误吗？是的，作为一种艺术，程序有自己的美学标准。从微观上看，这种美感表现为充分体现语言的优美和风格的简洁；从宏观来看则表现为一种层次清晰和条理分明。这种标准并不出于纯粹的审美，也有其功用价值——不容易出错，发生错误容易改正。而要达到这一目标，程序设计实践过程离不开正确的哲学指导，这种哲学的一个核心理念就是结构化程序设计思想。至此，尽管还有很多种类错误没有谈到，但是已经不难得出结论，程序设计错误很多。需要始终对错误保持警惕。应该如何对待程序设计中的错误首先，不要惧怕错误。错误尽管繁多，但只要了解认识错误就可以改正、避免错误。最可怕的是对错误的无知与鸵鸟般的无视。认识错误是改正错误的前提。
其次，了解错误越早越好，了解得越多越好。了解得越早进步得越快，了解得越多进步越大。第三，错误也是一种财富。既然从错误中积累经验是提高程序设计水平的必经之路，那么从他人的错误中吸取教训则是一种提高程序设计水平的捷径，因为所谓捷径无非就是少走弯路或不走弯路而已。本书的主要内容及特点本书汇集了大量C语言的错误和编程陋习，逐个予以详细讨论，这些错误主要取自国内发行量和影响力较大的C语言教科书及其他一些非教科书C语言书籍以及网络上比较流行的观点，主要包括□□□□□(为节约篇幅，此处删去286个字)，也有一些则是C语言本身的一些不易理解的特点以及学习者不具备良好的编程习惯所导致的错误。应该说本书所举出的反面例子非常具有代表性。本书分为上下两部，上部“形而下学”讨论代码中的常见错误和不良风格，下部“形而上学”讨论的是很多人对C语言持有的错误观点和认识。书中各个小节基本上是互相独立的，因此读这本书并不需要循序渐进，可以翻到哪页读哪页。什么人应该及什么人不应该看这本书对于使用国内教科书学习C 语言的人来说，无论是初学者还是职业程序员，这本书应该是很有价值的参考读物。因为本书的内容恰恰是教科书不讲的内容或恰恰是教科书讲错了的内容。如果是为了应付什么等级考试之类的话，就不需要浪费钱财了。看了此书你可能会发现那些考试本身也有很多错误。阅读指南如下形式，标注为“样本”的虚线框中的内容，是采样自教材或者互联网上值得商榷的说法或者代码。
如下形式，虚线框中的内容，是存在问题，或者说是不那么完美的说法或者代码。
如下形式，无虚线框中的内容，是没有问题的优质代码或相对准确的说法。#include <stdio.h> int main( void ) { 
char str1[5],str2[5],str3[5]; str1[4]='X'; str2[4]='X'; 
…… 虽然为写这本书花了近三年的时间，但最后完稿时，我发现这段时间依然显得非常短促。因此尽管这是一本讨论错误的书，但是毋庸讳言，它本身可能也免不了存在错误。您若在阅读时发现任何错误或不妥之处，欢迎与作者联系并通知作者：这里先谢了！
致谢本书的写作过程中得到了很多人的帮助和支持，在此作者表示深深的感谢。特别感谢starwing83网友的一贯支持和帮助，他对程序设计语言的深刻理解和丰富的实践经验不但让笔者受益匪浅，而且也使本书在许多方面得到了提高和充实。本书的第11章问题28、第18章问题10和第19章问题1为starwing83网友所撰写。特别感谢OwnWaterloo网友的一贯支持和帮助，他对标准的准确理解和对程序设计深刻的洞悉解开了笔者的很多疑惑，使作者在很多问题上都茅塞顿开。第5章“问
题19”为OwnWaterloo网友所撰写。特别感谢幻の上帝网友，在多年的共同探讨中，他热情而无私地给予作者很多支持、帮助和启迪。本书的很多观点受惠于幻の上帝网友的启迪，他还为本书收集了很多资料，为本书做了许多翔实的考证工作，并纠正了作者的很多错误。特别感谢诸多网友在长期的讨论中所给予的道义支持、精神鼓励和技术帮助，他们是：变异老鼠、shan_ghost、蔡万钊、狗气球、狗蛋、三月二十七、tempname2、x5miao、madoldman、walleeee、ChiyuT、davelv、huangzhenfan、花瓣雪、一介村夫、wait_rabbit、MMMX、rover12421、良化纲领_、assiss、gccer、8pm、supermegaboy、noword2k、hahajerry007、ztz0223、Ray001、fera、unixlinuxsys、cokeboL、koolcoy、sh19871122、群雄逐鹿中原、fender0107401、jerryz920、hellioncu、blueheavenljn、x2、lylesong、supersuper8、gaara99、Kabie、pkkj、rossini23、wolfkin、milujite、weixuejun、cnhbdu、yesBSD、kouu、chinesedragon、water_wf、gz80、toniz、eminem112、sunjiakuang、airjordanforce、yumaofsj、yug1129、campuspuzzle、www1862、zxrjkl、peijue、jhzhu_snps、x75yan、zhaohongjian000、tinysniper、xxwpk007、geel、字母二十六、奶茶dsk、abc976031617、rain_fish、amarant、财版、没本、grand508、star1983653、bill15、makeit、liexusong、pandaiam、txg531、kingwolf520、梅川内依酷、bukkake、wuxb45、hobbs136、cjaizss、greensnow、jhui66、luojiannx、耐心学习、xiaobenniao514、L_kernel、geruihai、erlangs、 CUXXXCU、ip200、Hongqiyaodao、dglwx、jhinux、xwxfirst、timesu、srdgame、septem776、liupingforarm、kellenforever、192redwolf、cobras、small_bee、gyarenas、jack4010、startn、rainysky、jimmyixy、litanhe、rubyish、Demon—Hunter、wuliming_sc、bigxu、xfoucs、时尚农民、yangxue1206、hukb_cu、jnbxzl0200157、tianshx、sukora、ux400、craneflyfly、autoasm、时间看来、Jokday、asuka2001、namiii、jeung、btdm123、lilery、wangzhen11aaa、nketc、KanonInD、ybh37、dahan16、digdeep126、keytounix、光明‐使者、gtv、SoforthHe、djsxut、oilgeo、呆呆的等候救赎、hbmhalley、china_ssl、solu、dajiangyou77、wl85125771、魔兽_LOVER、0xC1988、inzahgi、武林萌猪、lilinly225、wgm001、royalzhang、千年老狼、musezh2、gooderfeng、HAL9000、Jack_Jack、大石头、万仓一黍、Ivony、愚溪、nscboy、minvt、underuwings、Artech、ini_always、小彬、xujif、LeonSharp、刘博平、linyilong、浩然正气89、backag、happycat1988、ygcao、rhs、Zlinux、小_金_鱼、泡泡腾、SongSharp、szwe、eeeyes、+v、linxr、andreas、冠吸柏汁霆疯、九原山人、火禾、luotong、ProgrammerK、hachihe、rockyoung、czcz1024、Edgar.Wang、magicDict、hoodlum1980、空明流转、随风浪迹天涯、不死鸟之魂、木耳、木野狐(Neil.Chen)、散客游、sunriseyuen、chasefornone、飞浪、glshader、Credo、wcut、houqidian、Parry、xiekun605746、哥哥.Net、Virus‐BeautyCode、庄金峰、我想我是风、MienNg、soap、greenhand2008、Homer_Simpson、zsea、鎏、ctou45、shamo0303、gussing、eflay、王小兵、l23cy、winter‐cn、Lee.Kevin、阳光明媚Ryan、地狱门神、richardzeng、pulihe、寒霭、cncolder、陈玉国、是否存在、key.yao、codebumb、☆凯子、darklx、草珊瑚、鹤冲天、Jake.Lin、Lithium、干拔三分、leizisdu、zzuxiaolei、BitSky、Jeffrey.Zhao、桀骜的灵魂、海南.胡勇、sm11e、我写的不是代码是寂寞、lzyzizi、肖璟、嗷嗷、木+头、zy498420、№完成、五星、Simon‐Zhu、BeckFun、Tony.Zhou、lxlylm、陈梓瀚(vczh)、zdd、xchat、frank_hust、漂浮的雨、六芒星、MagicHu、天方、深蓝流沙、viperchaos、swfc_qinmm、潇湘雨歇、riccc、Jeff.Wong、wincss、reavics、weiwelcome0、Muse、lx458004975、镜美如、volcanol、路过秋天、徐少侠、南京.王清培、诺贝尔、蔺燕梅……这个名单可能有所遗漏，在此向被遗漏的网友表示歉意。特别感谢ChinaUnix论坛，在这个论坛的《以其昏昏使人昭昭》帖子中我完成了这本书的主要素材的积累。这个论坛良好的技术氛围使得本书素材的积累得以顺利进行。特别感谢博客园，作者在这个论坛发表的《C解毒》系列博文是本书的部分内容或草稿。在这个论坛得到了很多网友有益的反馈。本书在写作过程中参阅了大量网上技术资料，从中得到了很多启发，郑重向这些作者表示谢意。一位朋友根据《以其昏昏使人昭昭》帖子整理了一份文档，给本书的写作带来了极大的便利和帮助，在此深深表示感谢。薛非
图书目录
上部 形而下学——代码错误及陋习第1章 低级错误 3问题1 C啊，多少C++假汝之名而行——C、C++不分 4问题2 环节缺失——关于C程序开发过程 7问题3 错误的“标点”——混用中英文字符 9问题4 错误的“单词” 11问题5 “合并单词”产生的问题 12问题6 形形色色的“分号”误用 13问题7 “一仆二主”——两个main()函数 15问题8 忘记“&” 17问题9 who’s who 18问题10 同形异质——为符号常量赋值 19问题11 词不达意 20问题12 使用switch语句的常见错误 21第2章 初级错误 23问题1 随手写出的大数 24问题2 关于数据类型的潜规则 25问题3 使用垃圾值 26问题4 对数组的误用与误解 28问题5 好心办坏事——修改代码引发的错误 30问题6 “右移运算等价于除法运算” 32问题7 “中国人民很行”——C语言中的错别字 33问题8 学会数数——循环次数错误 34问题9 忽视函数原型 36问题10 张冠李戴——错误的格式转换 37问题11 只进不出——缺少输出 39问题12 鸠占鹊巢——数组越界 41第3章 逻辑错误 45问题1 喧宾夺主——换行问题 46问题2 结构体链表的一个例题——输出错误 47问题3 一些幼稚的写法 50问题4 c=getchar()!=EOF——优先级错误 50问题5 判断三个整数相等——“==”运算符的误用 51问题6 悬挂else问题——怎样写出正确的if语句 52问题7 浮点循环变量 53问题8 不顾常识 55问题9 自然语言的陷阱 57问题10 c==' ' || '\n' || '\t' 58问题11 乱做习题你伤不起啊 59问题12 误改循环变量 62第4章 似是而非 65问题1 void main() 66问题2 生硬的嫁接，滑稽的实参 66问题3 输出之误——输出数组应注意的问题 70问题4 多此一举 73问题5 笨拙的for语句 74问题6 只用printf()函数输出 76问题7 容易招致编译器误解的代码 76问题8 使用“//”注释注意事项 77问题9 使用野指针 78问题10 用驴子拖宝马——滥用结构体 79问题11 似是而非的k=sqrt(n) 84问题12 scanf("%s",&str) 88问题13 已知两边长求三角形面积——不完全函数参数 89问题14 对“c”转换说明符的误解 92问题15 多余的计算 93问题16 到处忙活与一劳永逸——函数类型声明位置问题 96问题17 半身不遂和粗中有细 99问题18 忽视前提 103问题19 char text[3][80]不是一篇文章，也并非3行文字 104问题20 不安全的gets()函数 108问题21 文件名残缺 109问题22 exit(0) 110问题23 舍近求远 112问题24 重复无效的代码 114问题25 拙劣的外部变量 114第5章 画蛇添足 129问题1 KISS 130问题2 为赋新词强说愁 131问题3 啰唆重复 132问题4 表达式是什么 133问题5 不识指针 134问题6 脱裤子放屁 136问题7 怎样利用scanf()函数自虐 138问题8 自寻烦恼的scanf()函数调用方式 139问题9 输入指定范围的整数——Basic风格写法和C风格写法 140问题10 “豆浆买两碗，喝一碗，倒一碗”——多余的数组元素 143问题11 筛法“四不像” 146问题12 不彻底的思考 152问题13 代码写得要“拽”(DRY) 156问题14 作茧自缚的“%3d” 158问题15 大腹便便——臃肿与重复 160问题16 舍简就繁 161问题17 程序的劣化与优化 163问题18 滥用变量综合症 172问题19 free空指针 174第6章 疑难杂症 177问题1 混乱是怎样炼成的 178问题2 无知乱吃药——strcpy()函数的误用 183问题3 边界测试——让BUG现形 186问题4 内裤外穿——错位及不伦不类 192问题5 flag标志：代码馊了（一） 196问题6 flag标志：代码馊了（二） 202问题7 flag标志：代码馊了（三） 210问题8 鸡窝里飞出伪凤凰 216问题9 不顾常识 221问题10 不易察觉的BUG 222问题11 含糊之过、多做之过及乱做之过 224问题12 怎样调戏程序 230问题13 糟蹋好题——魔方阵问题 236第7章 风格问题 249问题1 如何进行数组初始化 250问题2 括号不配对错误及如何免疫 251问题3 不良代码编辑风格引起的错误——怎样写控制语句 252问题4 将main()函数进行到底 253问题5 赤裸的scanf() 257问题6 c + 32的问题 257问题7 怎样整理房间 259问题8 贪小便宜——省略函数类型声明等问题 262问题9 常数Magic Number 265问题10 搏二兔 269下 部 形而上学——概念错误及误区第8章 概念的缺失 277问题1 C语言的历史及C标准 278问题2 只知变量不知对象 278问题3 C语言中Byte的含义 280问题4 “不知所云”的无定义行为（undefined behavior） 281问题5 “可以清心也”应如何解读——不确定行为（Unspecified behavior） 283问题6 实现（Implemantation） 285问题7 “编译器自己做主”——实现定义的行为 （implementation-defined behavior） 285问题8 整数提升（Integer promotion） 285问题9 副效应（side effects） 286问题10 “左值就是可以出现在赋值运算符的左侧” 287第9章 基本词法 289问题1 字符集问题 290问题2 “α，β，δ，ε，Ⅰ，Ⅱ，Ⅲ，Ⅳ等不是C语言的合法字符” 291问题3 “各种字符集的基本集都包括了127个字符” 291问题4 C源程序的组成——“单词”视角 292问题5 “a”、‘a’与a辨析 293问题6 “C语言关键字都是小写的” 294问题7 “C语言允许一行内写多个语句” 294问题8 “标识符由字母、下划线和数字组成” 295问题9 标识符的长度限制 295问题10 “括号、赋值、逗号都是运算符” 296第10章 数据类型及类型转换 297问题1 “类型就是对数据存储单元的安排” 298问题2 1.%3之惑 298问题3 “int为2个字节或4个字节” 299问题4 int类型的范围问题 299问题5 混乱不堪的“整型” 300问题6 “?345是整型常量” 300问题7 “字符数据以ASCII码存储” 301问题8 “char类型就是signed char类型” 301问题9 通过程序测定char类型的性质 302问题10 “C用1个字节（8位）存储一个字符” 302问题11 “i='A'是字符型数据赋给整型变量” 303问题12 “字符常量只能是一个字符” 303问题13 “从常量的表示形式可以判断其类型” 303问题14 1、'1'与"1" 304问题15 “变量值在存储单元中都是以补码形式存储的” 304问题16 “不应向无符号整型变量赋予一个负值” 305问题17 3.0乘以4.2怎么就变成了12.59999 306问题18 “实型变量”剖析 307问题19 使用float招来的警告及“因噎废食”的对策 307问题20 123f——怎样写float类型的常量 309问题21 “实型常量有两种表示形式” 309问题22 “浮点数类型包括float、double和long double” 310问题23 “实数就是浮点数” 310问题24 “编译系统为每一个float型变量分配4个字节” 310问题25 “浮点型”、“双精度浮点型”和“实型” 311问题26 “Turbo C对long double 型分配16个字节” 311问题27 “必然以规范化的指数形式输出” 311问题28 “浮点型数据是用来表示具有小数点的实数的” 312问题29 对类型转换运算的误解 312问题30 “整型量与字符型数据以及逻辑型数据可以通用” 312问题31 “C语言把所有的实数都作为双精度数处理” 314问题32 “所有float型数据都先转换为double型” 314问题33 “int型与float或double型数据进行运算，结果是double型” 315问题34 关于char类型数据的运算规则 316问题35 对表达式“10+'a'+i*f-d/3”的分析 316问题36 “字符数据既可以字符形式输出，也可以整数形式输出” 318问题37 3 ? 1∶2. 319问题38 “运算符两侧的数据类型不同，先自动进行型转换” 319第11章 运算和表达式(Expression) 321问题1 关于“整型常量” 322问题2 “变量名是以一个名字代表一个存储地址” 323问题3 “缺省情况下所有变量都是auto 的” 324问题4 “不能对一个类型赋值、存取或运算” 324问题5 “变量必须先定义、后使用” 324问题6 “常量是没有名字的不变量” 325问题7 “标识符用来标识一个对象” 325问题8 啥叫“中间变量” 326问题9 “先乘除后加减”——“优先级高先运算” 326问题10 “赋值截断” 326问题11 对(a=b)>0 的误读 327问题12 “‘.’运算符优先级高于后缀‘++’运算符” 327问题13 “‘结合性’是C语言的特点之一” 327问题14 “‘左结合性’，即运算对象先与左面的运算符相结合” 328问题15 “算术表达式”和“算术运算符”：两个臆造的伪概念 328问题16 关于“算术表达式”、“优先级”和“结合性”的胡扯 330问题17 “C语言共有34种运算符” 333问题18 “两个实数相除的结果是双精度实数” 334问题19 整数除法的舍入方向问题 335问题20 “++运算的作用是使变量的值加1” 335问题21 为a+=a-=a*a预拟的悼词 335问题22 &&的运算规则 339问题23 对“5>3&&8<4-!0”的分析 340问题24 逻辑运算符和逻辑表达式 341问题25 “二元运算符都可以与赋值符一起组合成复合赋值符” 342问题26 “赋值运算符的作用是将一个数据赋给一个变量” 343问题27 “执行表达式a=(b=5)，就是执行b=5和a=b两个赋值表达式” 343问题28 类型系统？表达式？副效应？——C的“易筋经” 343问题29 GB/T15272-94的一个错误 346问题30 sizeof“函数” 347问题31 逗号运算符是几目运算符 348问题32 怎样滥用逗号运算符 348问题33 “逗号运算符最常用于循环语句” 349问题34 同名不同义的运算符：“++”与“++” 350问题35 ++、--的运算对象问题 351问题36 自增运算符(++)不能用于表达式 351问题37 cast运算的优先级问题 352第12章 声明和语句 355问题1 “全局变量” 356问题2 声明外部变量时省略类型名称 356问题3 声明点(Declaration point)的问题 358问题4 指向静态整型变量的指针 359问题5 存储类别 359问题6 “输出语句”及“赋值语句” 360问题7 “函数调用语句” 360问题8 “C语言规定语句末尾必须有分号” 361问题9 switch语句的一般形式 362问题10 switch语句中的表达式类型问题 363问题11 “while语句的范围只到while后面第一个分号处” 364问题12 “for语句和while语句无条件等价” 364问题13 “语句的作用是向计算机系统发出操作指令，要求执行相应的操作” 365第13章 函数 367问题1 “实际参数可以是常量、变量或表达式” 368问题2 “函数调用的形式” 368问题3 “虚拟参数”和“虚实结合” 369问题4 “值传递”和“址传递” 369问题5 函数的指针是起始地址 371问题6 用指针调用函数 371问题7 “void意为函数无类型” 372问题8 “函数必须‘先定义后使用’” 372问题9 “使用函数原型作声明是C的一个重要特点” 373问题10 “函数体包括声明部分和执行部分” 373问题11 “库函数是编译系统事先定义好的” 374问题12 “定义无参函数的一般形式” 374问题13 “不带回值的函数的函数体中不得出现return语句” 374问题14 过时的函数定义 375问题15 “不能调用main函数” 376问题16 “C程序在main()函数中结束” 376问题17 五花八门的main()函数 377问题18 “函数名代表函数的入口地址” 384问题19 “函数声明”、“函数原型”与“函数定义”辨析 385第14章 指针 389问题1 指针的种类问题 390问题2 “指针就是一个变量” 390问题3 “指针就是地址” 391问题4 “一元‘&’是取地址运算符” 393问题5 错误观念下的代码 393问题6 返回指向局部变量的指针 396问题7 野指针问题 396问题8 “指针是32位的无符号的整数” 397问题9 “指针的大小都一样” 397问题10 “无类型指针” 397问题11 指针加减法运算的“定义域” 398问题12 const 悖论 400问题13 不经意的错误：&a[10] 与a+10的差异 403问题14 新编《守株待兔》——C语言版——兼聊为什么不应该用%d格式转换输出指针 403第15章 数组和字符串 407问题1 定义一维数组的一般形式 408问题2 何谓“可变长数组” 408问题3 “字符串是存放在字符型数组中的” 409问题4 “数组中未被赋值的元素的值自动置'\0'” 410问题5 “数组名不是左值” 411问题6 数组名“只代表数组首元素的地址” 412问题7 辨析“形参和实参可以分别用字符数组名或字符指针变量” 414问题8 关于strncpy()函数的功能 415问题9 “数组名作函数参数”问题 416问题10 怎样称呼字符串 418问题11 小气的数组和危险的输入——慎用scanf()函数和gets()函数 420问题12 修改字符串文字量 421问题13 对strcpy()功能断章取义的描述 422第16章 结构体、共用体、枚举及位运算 425问题1 成员运算问题 426问题2 “->”称为指向运算符 426问题3 “只能对最低级的成员进行赋值或存取以及运算” 426问题4 63、64还是68？——谈谈alignment 428问题5 结构体的尺寸问题 431问题6 空结构体的尺寸问题 431问题7 “结构体变量的地址主要用作函数参数” 432问题8 “共用体变量所占内存长度等于最长成员的长度” 432问题9 “不能引用共用体变量” 433问题10 “不能对共用体变量名赋值” 435问题11 “枚举变量的值限定在定义时规定的几个枚举元素范围内” 435问题12 “‘位运算’是C语言区别于其他高级语言的一个重要特点” 436问题13 “参加位运算的对象只能是整型或字符型的数据” 437问题14 “‘<<’用来将一个数的各二进制位全部左移若干位” 438问题15 不同长度的数据进行位运算 439问题16 用memcmp()函数比较两个结构体 439第17章 标准库 441问题1 “%c转换说明符用于输入单个字符”引发的潜在BUG 442问题2 “对无符号整型数据用%u输出” 442问题3 “double类型应该用‘%lf’输出” 443问题4 关于%g格式的错误认识 443问题5 关于%o格式的错误认识 444问题6 “gets()函数是fgets()函数用于stdin的特例” 445问题7 “用puts函数输出的字符串中可以包含转义字符” 447问题8 “文件结束标志EOF(即-1)” 447问题9 “fseek(fp、100L、0)” 448问题10 打开文件时的两种错误 448问题11 “用"a"方式打开文件应保证文件事先存在” 449问题12 “在程序中可以直接用FILE类型名定义变量” 449问题13 “stdin是指向标准输入流的指针变量” 449问题14 关于feof()函数的错误 450问题15 “度日如年”的故事及“feof()函数”的故事 450问题16 关于fflush()函数的错误 455问题17 盲目前行——忽视malloc()函数返回值 457问题18 管杀不管埋——缺少free()函数 458问题19 怎样建立链表并同时造成内存泄漏 459问题20 qsort()函数是快速排序 462问题21 关于calloc()函数 462问题22 关于free()函数 463问题23 关于realloc()函数 464问题24 为什么不可以static char*p=malloc(10); 464问题25 abs()是数学函数 465第18章 预处理 467问题1 “预处理功能是C语言特有的” 468问题2 主动引进BUG 468问题3 “#define是用一个指定的标识符来代表字符串” 469问题4 “预处理器把程序中的注释全部删除” 470问题5 “所有的PI都代表3.1416” 470问题6 #define预处理命令的位置问题 471问题7 能否用痰盂盛饭——谈在头文件中定义外部变量 472问题8 预处理次序错误 475问题9 缺少#include 476问题10 包含源文件——是奇技淫巧还是饮鸩止渴 476问题11 使用函数式宏的禁忌 480问题12 不合格的宏 481问题13 “宏实参从左到右进行置换” 481问题14 条件编译与if语句 482第19章 关于C99 485问题1 亡羊补牢还是越错越远——“C99允许在函数中的复合语句中定义变量” 486问题2 C99增加了哪些数据类型 488问题3 “C99标准不支持一行内写多个语句” 489问题4 “C99把字符型数据作为整数类型的一种” 489问题5 “C99要求main函数一律指定为int型” 489问题6 “C99允许使用常变量” 490问题7 “C99允许使用多字节字符” 490问题8 “C99允许使用基类型为void的指针类型” 490问题9 “C99增加了C++中的功能” 490问题10 “C99允许同类型的共用体变量互相赋值” 491问题11 能否用Visual C++ 6.0学习C99 491第20章 杂七杂八 493问题1 “系统描述语言”与“系统编程语言” 494问题2 关于计算机指令长度 494问题3 同一律 494问题4 为什么不能用汇编解释C 495问题5 “文件中的物理顺序” 495问题6 “C语言源程序的扩展名为.c” 496问题7 缺乏测试意识 496问题8 为Wirth正名 499问题9 “bohra”是谁 500问题10 “83 ANSI C”和“87 ANSI C” 500问题11 关于ISO 501问题12 关于勒让德多项式 501参考文献 502[1]