C陷阱与缺陷-疑难问题理解
文章平均质量分 89
图解编程
热爱&分享
展开
-
C陷阱与缺陷-疑难问题理解01
概述 课程“C陷阱与缺陷-疑难问题理解”是笔者在学习《C陷阱与缺陷》这本书时的读书记录,进行二次创作而成。通过“讲义+视频”方式帮助大家在短时间内学习《 C陷阱与缺陷》这本书,进而提升对C语言的理解。同时也是对自己学习成果的巩固。讲义和视频免费获取并且全部开源。 不知道你有没有这种感觉!总是觉得自己对C语言基本的语法和使用很了解,但是涉及到C语言的高级用法有总是感觉似懂非懂。另外通过视频方式自学C语言知识也感觉不完整,如果没有看书像是缺了点什么!认为看书才算是系统的学习。 通过在网上查找资原创 2021-07-05 14:03:20 · 148 阅读 · 1 评论 -
C陷阱与缺陷-疑难问题理解02
第一章 词法“陷阱” 当我们阅读一个句子时,我们并不去考虑组成这个句子的单词中单个字母的 含义,而是把单词作为一个整体来理解。字母本身并没有什么意义,我们总是将字母组成单词,然后给单词赋予一定的意义。 对于用C语言或其他语言编写的程序,道理也是一样的。程序中的单个字符孤立来看并没有什么意义,只有结合上下文才有意义。因此,在p->s = “->”;这个语句中,两处出现的’-'字符的意义大相径庭。 术语“符号”指的是程序的一个基本组成单元,其作用相当于一个句子中的单词。编译器中负责原创 2021-07-06 23:05:02 · 132 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解03
第2章 语法“陷阱” 要理解一个C程序,仅仅理解组成该程序的符号是不够的。程序员还必须理解这些符号是如何组合成声明、表达式、语句和程序的。虽然这些组合方式的定 义都很完备,几乎无懈可击,但有时这些定义与人们的直觉相悖,或者容易引起混淆。本章将讨论一些用法和意义与我们想当然的认识不一致的语法结构。2.1 理解函数声明 当计算机启动时,硬件将调用首地址为0位置的子例程。为了模拟开机启动时的情形,我们必须设计出一个C语句,以显式调用该子 例程。经过一段时间的思考,我们最后得到的语句如下:(*原创 2021-07-05 14:08:10 · 137 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解04
2.3 注意作为语句结束标志的分号 在c程序中如果不小心多写了一个分号可能不会造成什么不良后果:这个分号也许会被视作一个不会产生任何实际效果的空语句;或者编译器会因为这个多余的分号而产生一条警告信息,根据警告信息的提示能够很容易去掉这个分号。一个重要的例外情形是在if或者while语句之后需要紧跟一条语句时,如果此时多了一个分号,那么原来紧跟在if或者while子句之后的语句就是一条单独的语句,与条件判断部分没有了任何关系。考虑下面的这个例子;if (x[i] > big);big =原创 2021-07-05 14:09:11 · 124 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解05
第3章 语义“陷阱” 一个句子哪怕其中的每个单词都拼写正确,而且语法也无懈可击,仍然可能有歧义或者并非书写者希望表达的意思。程序也有可能表面看上去是一个意思,而实 际上的意思却相去甚远。本章考察了若干种可能引起上述歧义的程序书写方式。 这一章中还讨论了这样的情形:如果只是肤浅地考察,一切都“显得”合情 合理,而事实上这种情况在所有的C语言实现中给出的结果却都是未定义的。在 某些C语言实现中能够正常工作,而在另一些C语言实现中却又不能工作的情形, 这属于可移植性方面的问题,将在第7章中给予论述。原创 2021-07-05 14:09:48 · 149 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解06
3.4 避免”举隅 [yú] 法”“举隅法”(synecdoche)是一种文学修辞上的手段,有点类似于以微笑表示喜悦、赞许之情,或以隐喻表示指代物与被指物的相互关系。在《牛津英语辞典》 中,对“举隅法”(synecdoche)是这样解释的:“以含义更宽泛的词语来代替含 义相对较窄的词语,或者相反;例如,以整体代表部分,或者以部分代表整体, 以生物的类来代表生物的种,或者以生物的种来代表生物的类,等等。”《牛津英语辞典》中这一词条的说明,倒是恰如其份地描述了 C语言中一个 常见的“陷阱”:混淆指针与指原创 2021-07-05 14:10:31 · 252 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解07
1.7 求值顺序运算符优先级是关于诸如表达式a + b * c应该被解释成a + (b * c)而不是(a + b) * c的这样一类规则。求值顺序是另一类规则,可以保证像下面的语句if(count != 0 && sum/count < smallaverage) printf("average <%g\n",smallaverage);即使当变量count为0时,也不会产生一个“用0作除数”的错误。C语言中的某些运算符总是以一种已知的、规定原创 2021-07-05 14:11:35 · 104 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解08
第4章 连接 一个C程序可能是由多个分别编译的部分组成,这些不同部分通过一个通常叫做连接器(也叫连接编辑器,或载入器)的程序合并成一个整体。因为编译器一般每次只处理一个文件,所以它不能检测出那些需要一次了解多个源程序文件才能察觉的错误。而且,在许多系统中连接器是独立于C语言实现的,因此如果前述错误的原因是与C语言相关的,连接器对此同样束手无策。 某些C语言实现提供了一个称为lint的程序,可以捕获到大量的此类错误, 但遗憾的是并非全部的C语言实现都提供了该程序。如果能够找到诸如lint的程 序原创 2021-07-05 14:11:58 · 181 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解09
第5章 库函数 C语言中没有定义输入/输出语句,任何一个有用的C程序(起码必须接受零个或多个输入,生成一个或多个输出)都必须调用库函数来完成最基本的输入/ 输出操作。ANSI C标准毫无疑问地意识到了这一点,因而定义了一个包含大量标准库函数的集合。从理论上说,任何一个C语言实现都应该提供这些标准库函数。ANSI C中定义的标准库函数集合并不完备。例如,基本上所有的C语言实现都包括了执行“底层”I/O操作的read和write函数,但是这些函数却并没有出现在 ANSI C标准中。而且,并非所有的C语言原创 2021-07-05 14:12:54 · 151 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解10
第6章 预处理器在严格意义上的编译过程开始之前,C语言预处理器首先对程序代码作了必 要的转换处理。因此,我们运行的程序实际上并不是我们所写的程序。预处理器 使得编程者可以简化某些工作,它的重要性可以由两个主要的原因说明(当然还 有一些次要原因,此处就不赘述了)。第一个原因是,我们也许会遇到这样的情况,需要将某个特定数量(例如, 某个数据表的大小)在程序中出现的所有实例统统加以修改。我们希望能够通过 在程序中只改动一处数值,然后重新编译就可以实现。预处理器要做到这一点可 以说是轻而易举,即使这个数值在程原创 2021-07-05 14:13:40 · 154 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解11
第7章 可移植性缺陷 C语言在许多不同的系统平台上都有实现。的确,使用C语言编写程序的一 个首要原因就是,C程序能够方便地在不同的编程环境中移植。 然而,由于C语言实现是如此之多,各个实现之间有着或多或少的细微差别, 以至于没有两个实现是完全相同的。即使是写得最早的两个C语言编译器,它们 之间也有着很大区别。此外,不同的系统有不同的需求,因此我们应该能够料到, 机器不同则其上的C语言实现也有细微差别。ANSI C标准的发布能够在一定程 度上解决问题,但并不是万验灵药。 早期的C语言实现都原创 2021-07-06 22:59:59 · 133 阅读 · 0 评论 -
C陷阱与缺陷-疑难问题理解12
7.7 除法运算时发生的截断假定我们让a除以b,商为q,余数为r :q = a / b;r = a % b;这里,不妨假定b大于0。我们希望a、b、q、r之间维持怎样的关系呢?最重要的一点,我们希望q*b + r==a,因为这是定义余数的关系。如果我们改变a的正负号,我们希望这会改变q的符号,但这不会改变q 的绝对值。当b>0时,我们希望保证r>=0且r<b。例如,如果余数用于哈希表的索引, 确保它是一个有效的索引值很重要。这三条性质是我们认为整数除原创 2021-07-06 22:59:41 · 142 阅读 · 0 评论