Chapter_01 穿越时空的迷雾

  • 1.1
编译器的效率包括两个方面:运行效率(代码的运行速度)和编译效率(产生可执行代码的速度),运行效率起决定性作用;
Ken Thompson在PDP-11上重新用汇编语言实现了UNIX,DR创立了能够同时解决多种数据类型和效率的“New B”语言(C),采用编译模式而不是解释模式,并引入类型系统,每个变量在使用前必须先声明。
  • 1.2
C语言增加类型系统的主要目的是帮助编译器设计者区分新型PDP-11所拥有的不同数据类型(单精度、双精度浮点数、字符等);
由于设计哲学,C语言排斥强类型(隐式转换,数组可以越界,几乎没有任何运行期的类型检查,允许在不同类型的对象间赋值);
C语言有着许多为了方便编译器设计者而建立的规则:
  1. 数组下标从0开始而不是从1开始。——偏移量的概念在编译器设计者心中根深蒂固。
  2. 基本数据类型直接与底层硬件相对应。——不存在内置的复数类型。
  3. 作为摆设的auto关键字。——这个关键字只对创建符号表入口的编译器设计者有意义,变量的默认修饰符,表示其作用域为当前函数或代码段,在进入该变量作用域的时候自动进行内存分配,对应于static。
  4.  数组名等同于指针。
  5. float被自动扩展为double。——只是在早期而已,现在的ANSI C不再如此。其与PDP-11中浮点数的硬件表示方式有关。
  6. 不允许嵌套函数。——简化了编译器的设计。
  7. register关键字。——简化编译器的设计,编译器只需要将其修饰的变量存放到寄存器即可。
and so on。
C语言对直接由硬件支持的底层操作的强调,带来了极高的效率和移植性,帮组UNIX获得了巨大的成功。
  • 1.3 
C语言最初并没有定义I/O,而是由库函数提供,可移植的I/O最早出现在1972年左右,但实践表明,其性能低于预期值,经过优化与剪裁,后来成为了标准的I/O函数库。
C预处理器的3个主要功能:
  1. 字符串替换。——通常用于为常量提供一个符号名。
  2. 头文件包含(BCPL中首创)。——一般性的声明被分离到头文件,并可以被许多源文件使用。
  3. 通用代码模板的扩展。——宏在连续几个调用中所接收的参数的类型可以不同。
总之,对于宏这样的预处理器,只应该适量使用。最好只用于命名常量,并为一些适当的结构提供简洁的记法。
  • 1.4
1978年,pcc这个可移植的C编译器,形成了整整一代C编译器的基础。同年,K&R C 诞生。
  • 1.5 ANSI C
Microsoft为IBM PC制作的C编译器,引入了几个新的关键字(far,near等)帮助指针处理x86芯片不规则的架构,但是其最终还是未被纳入以UNIX为中心的相对谨慎的ANSI C标准。标准认为不应该通过修改语言来处理某个特定平台所存在的限制。
1989年12月,C语言标准草案最终被ANSI接纳(C89),随后,ISO在删除了“Rationale”一节后也接纳了ANSI C标准。1990年,ANSI重新采纳了ISO C,取代原先的版本。标准C应该是ISO C。
  • 1.6
ANSI C标准的用于描述某种编译器的特定几个术语。
不可移植的代码(unportable code)相关的两个术语:
  1. 由编译器定义的(implementation-defined)——在不同的编译器中所采取的行为可能并不相同。
  2. 未确定的(unspecified)——在某些正确情况下的做法,标准并未明确规定应该怎样做。
坏代码(bad code)相关的两个术语:
  1. 未定义的(undefined)——在某些不正确情况下的做法(数据溢出),标准并未规定应该怎样做。
  2. 约束条件(a constraint)——一个必须遵守的限制或要求。
可移植的代码(portable code)相关的两个术语:
  1. 严格遵循标准的(strictly-conforming)——只使用已确定的特性;不突破任何由编译器实现的限制;不产生任何依赖由编译器定义的或未确定的或未定义的特性的输出。
  2. 遵循标准的(conforming)——可以依赖一些某种编译器特有的不可移植的特性。
  • K&R C 与ANSI C 之间的区别
  1. 非常不同很重要的区别。——函数原型(prototype)。函数原型使得编译器很容易根据函数的定义来检查函数的用法。
  2. 增加了一些新的关键字。——ANSI 增加的enum,const,volatile,signed,void。
  3. “安静的改变”。——原先的语言特性仍然合法,但其意思有了一些轻微的改变。
  4. 除去上面的所有区别。——三字母词(trigraph)。
  • 1.10
K&R C采用无符号保留(unsigned preserving)原则——当一个无符号类型与int或更小的类型混合使用时,结果类型是无符号类型。
ANSI C采用值保留(value preserving)原则——当几个整型操作数混合使用时,结果类型取决于操作数的类型的相对大小。
  • 1.11
ANSI C标准引入了pragma指示符,这个指示符来源于Ada。
1.34中#pragma的彩蛋。
posted @ 2013-12-13 13:28  qdsclove  阅读(245)  评论(0编辑  收藏  举报