1.7 疑难解惑
疑问1 C++与C的区别是什么?
C++与C的最大区别在于解决问题的思想方法不一样。之所以说C++比C更先进,是因为“设计”这个概念已经融入C++中,而就语言本身而言,在C中更多的是“算法”的概念。那么是不是C就不重要了?不是。算法是程序设计的基础,好的设计如果没有好的算法,一样不行。而且,“C加上好的设计”也能写出非常好的东西。
疑问2 C++的编译过程是怎样的?
首先是预编译,这一步可以粗略地认为只做了一件事情,那就是“宏展开”,也就是对那些“#***”的命令的一种展开。例如#define MAX 1000就是建立起MAX和1000之间的对等关系,好在编译阶段进行替换。例如,ifdef/ifndef就是从一个文件中有选择性地挑出一些符合条件的代码交给下一步的编译阶段来处理。这里面最复杂的莫过于include,其实也很简单,相当于把那个对应的文件里面的内容一下子替换到这条#include***语句的地方来。
其次是编译,这一步很重要。编译是以一个个独立的文件作为单元的,一个文件就会编译出一个目标文件(编译器通过后缀名来辨识是否编译该文件,因此“.h”的头文件一概不理会,而“.cpp”的源文件一律都要被编译,编者实验过把.h文件的后缀名改为.cpp,然后在include的地方相应地改为***.cpp,这样一来,编译器就会编译许多不必要的头文件,只不过头文件里我们通常只放置声明而不是定义,因此最后链接生成的可执行文件的大小是不会改变的)。清楚编译是以一个个单独的文件为单元的,这一点很重要,因此编译只负责本单元的那些事,而对外部的事情一概不理会,在这一步里,我们可以调用一个函数而不必给出这个函数的定义,但是要在调用前得到这个函数的声明(其实这就是include的本质,不就是为了给你提前提供个声明而好让你使用吗?至于那个函数到底是如何实现的,需要在链接这一步里去找函数的入口地址。因此提供声明的方式可以是用include把放在别的文件中的声明拿过来,也可以在调用之前自己写一句void max(int,int);)。编译阶段剩下的事情就是分析语法的正确性之类的工作。总结一下,可以粗略地认为编译阶段分两步:第一步,检验函数或者变量是否存在它们的声明;第二步,检查语句是否符合C++语法。
最后一步是链接。它会把所有编译好的单元全部链接为一个整体文件。其实这一步可以比作一个“连线”的过程,比如A文件用了B文件中的函数,那么链接的这一步会建立起这个关联。编者认为链接时最重要的是检查全局空间里面是否有重复定义或者缺失定义。这也就解释了为什么一般不在头文件中出现定义,因为头文件有可能被释放到多个源文件中,每个源文件都会单独编译,链接时就会发现全局空间中有多个定义了。
疑问3 C++都有什么版本?
目前,C++的标准是C++语言国际标准最新版ISO/IEC 14882.2011。
1998年,国际标准组织(ISO)颁布了C++程序设计语言的国际标准ISO/IEC 1488-1998。C++是具有国际标准的编程语言,通常称为ANSI/ISO C++。1998年是C++标准委员会成立的第一年,以后每5年视实际需要更新一次标准。遗憾的是,由于C++语言过于复杂,以及它经历了长年的演变,Visual C++ 2010 CTP开发环境的编译器只是完全符合C++0x(2009年发布)这个标准。