第1单元Hel,C++ 第1单元Hell,C++! 本单元教学目标 介绍C++程序的基本结构以及在计算机上输入、编译、调试和运行C++程序的基本方 法和步骤 学习要求 了解C++程序的基本特点,熟悉 Visual C++集成开发环境的基本使用方法。 授课內容 11软件开发与C++语言 我们知道,使用计算机工作是通过相应的应用软件进行的,如用于文字处理的word, 科学计算的 MATLAB,表格处理的 EXCEL和各种数据库软件等,这些软件均由专业软件开 发人员设计编程。一般来说,日常工作中遇到的任务大多数均可借助现成的应用软件完成, 但有时仍需为具体问题自行开发相应的软件。特别是在工程应用领域中,解决各类项目中可 能遇到的大量具体问题,使用通用的软件不仅效率低下,还可能无法完成任务。在这种情况 下,自行编制具有针对性的相应软件可能是唯一的解决方法 为计算机编写软件需要使用程序设计语言。目前可用的计算机语言很多,各有其特点。 有些适用于开发数据库应用程序,有些适用于开发科学计算程序,有的简便易学,有的功能 全面。在本课程中,我们介绍 Visual C+语言 Visual c++语言支持面向对象的程序设计方法,适用于 WINDOWS应用程序的开发,可 用于开发各类应用程序,功能十分强大,是目前最流行的程序设计语言之一。本教程以面向 对象的程序设计方法为中心,本着简明、实用和循序渐进的原则,介绍使用Ⅴ isual C++开发 应用程序的基本方法 12算法与程序 要编写用于解决应用问题的程序,首先必需确定解决问题的方案,也就是算法。例如, 对于问题:给定两个正整数p和q,如何求出其最大公因数?古希腊数学家欧几里德( Euclid) 给出了一个著名的算法 步骤1:如果p<q,交换p和q 步骤2:求p/q的余数
第 1 单元 Hello,C++! - 1 - 第 1 单元 Hello, C++! 本单元教学目标 介绍C++程序的基本结构以及在计算机上输入、编译、调试和运行C++程序的基本方 法和步骤。 学习要求 了解C++程序的基本特点, 熟悉 Visual C++集成开发环境的基本使用方法。 授课内容 1.1 软件开发与C++语言 我们知道, 使用计算机工作是通过相应的应用软件进行的, 如用于文字处理的 Word, 科学计算的 MATLAB, 表格处理的 EXCEL 和各种数据库软件等, 这些软件均由专业软件开 发人员设计编程。一般来说, 日常工作中遇到的任务大多数均可借助现成的应用软件完成, 但有时仍需为具体问题自行开发相应的软件。特别是在工程应用领域中, 解决各类项目中可 能遇到的大量具体问题, 使用通用的软件不仅效率低下, 还可能无法完成任务。在这种情况 下, 自行编制具有针对性的相应软件可能是唯一的解决方法。 为计算机编写软件需要使用程序设计语言。目前可用的计算机语言很多, 各有其特点。 有些适用于开发数据库应用程序, 有些适用于开发科学计算程序, 有的简便易学, 有的功能 全面。在本课程中, 我们介绍 Visual C++语言。 Visual C++语言支持面向对象的程序设计方法, 适用于 WINDOWS 应用程序的开发, 可 用于开发各类应用程序, 功能十分强大, 是目前最流行的程序设计语言之一。本教程以面向 对象的程序设计方法为中心, 本着简明、实用和循序渐进的原则, 介绍使用 Visual C++开发 应用程序的基本方法。 1.2 算法与程序 要编写用于解决应用问题的程序, 首先必需确定解决问题的方案, 也就是算法。例如, 对于问题: 给定两个正整数 p 和 q, 如何求出其最大公因数? 古希腊数学家欧几里德 (Euclid) 给出了一个著名的算法: 步骤 1: 如果 p < q, 交换 p 和 q; 步骤 2: 求 p/q 的余数 r;
第1单元Hel,C++ 步骤3:如果r=0,则q就是所求的结果 否则反复做如下工作 令p=q,q=r,重新计算p和q的余数r,直到r=0为止 则q就是原来的两正整数的最大公因数 从原则上说,有了算法,人们就可以借助纸、笔和算盘等工具直接求解问题了。但如果 问题比较复杂,计算步骤很多,则应通过编程,使用计算机解决。 [例1-1]使用欧几里德算法,编写一程序求解任意两正整数的最大公因数。 说明:根据163:“用 Developer Studio编写和调试简单C++程序”建立项目并调 试和运行。 程序 ∥/ Example1-1:计算两个正整数的最大公因数 Include void main ∥/声明三个整型变量p,q /提示用户由键盘输入两个正整数 cout> p>> /如果p<q,交换p和q p q /计算p除q的余数r /只要r不等于0,重复进行下列计算 hile( p=q //输出结果 cout <<The maximum common divisor is<< g<< "."< endl 输入数据:输入两个整数,其间以空格分隔。如
第 1 单元 Hello,C++! - 2 - 步骤 3: 如果 r = 0, 则 q 就是所求的结果; 否则反复做如下工作: 令 p = q, q = r, 重新计算 p 和 q 的余数 r,直到 r = 0 为止 则 q 就是原来的两正整数的最大公因数. 从原则上说, 有了算法, 人们就可以借助纸、笔和算盘等工具直接求解问题了。但如果 问题比较复杂, 计算步骤很多, 则应通过编程, 使用计算机解决。 [例 1-1] 使用欧几里德算法, 编写一程序求解任意两正整数的最大公因数。 说 明:根据 1.6.3:“用 Developer Studio 编写和调试简单 C++程序”建立项目并调 试和运行。 程 序: // Example 1-1: 计算两个正整数的最大公因数 #include void main() { // 声明三个整型变量 p, q, r int p, q, r; // 提示用户由键盘输入两个正整数 cout> p >> q; // 如果 p < q, 交换 p 和 q if(p<q) { r = p; p = q; q = r; } // 计算 p 除 q 的余数 r r = p%q; // 只要 r 不等于 0, 重复进行下列计算 while(r != 0) { p = q; q = r; r = p%q; } // 输出结果 cout << "The maximum common divisor is " << q << “.” << endl; } 输入数据: 输入两个整数,其间以空格分隔。如 12 18
第1单元Hel,C++ 输出数据: The maximum common divisor is6 分析:可以看出,该程序的主体部分几乎与原算法完全相同,只是增加了一些 语言特有的内容 程序的第1行是注解。注解以“∥”开头,直到该行的末尾,用于说明或解释程序段的 功能、变量的作用以及程序员认为应该向程序阅读者说明的任何内容。可以看到,在该程序 中还有一些注解,用于说明程序的结构。在将C++程序编译成目标代码时所有的注解行都会 被忽略掉,因此即使使用了很多注解也不会影响目标码的效率。恰当地应用注解可以使程序 清晰易懂、便于调试,便于程序员之间的交流与协作,因此在自己编写的每个程序中都使用 精心撰写的注解是一个良好的编程习惯。C++中还有一种注解格式,可参看1.5.2。 第2行是编译预处理,有关内容将在1.5.5节介绍。 从第3行到最后一行,是主函数。主函数是该程序的主体部分,由其声明部分 void main() 和用一对花括号{}括起来的函数体构成。在函数体内,除了注解行以外,还有语句。C++ 的语句可分为声明语句和执行语句,声明语句用于声明程序中使用的变量、函数等的类型和 参数,执行语句实际执行某功能。第5行就是一个类型声明语句 int p, g 声明在该程序中使用了3个整型变量。关于类型和变量等概念,将在第3单元中详细介绍 就一般的计算机程序而言,总是要包括三个基本内容:数据输入、计算和输出 该程序的输入部分首先在计算机屏幕上显示一行提示信息(第7行) Please input two integer numbers 然后等待使用者由键盘输入两个整数。用户输入的两个正整数由语句 cin > p>>q 分别存入变量p和q 程序下面的部分就是欧几里德算法的具体实现了。可以看出,C++程序类似自然语言,只 是结构更加严谨,对照前面的算法不难理解 程序中的最后一个语句是输出语句,将计算结果显示在计算机屏幕上 13输入、编译、调试和运行一个C++程序 C+是一种编译语言,C++源程序需要经过编译、连接,生成可执行文件后方可运行 使用C++开发一个应用程序大致要经过以下步骤: 1.首先要根据实际问题确定编程的思路,包括选用适当的数学模型。这方面的内容其实 也是各应用学科的主要研究领域之一; 2.根据前述思路或数学模型编写程序。除了非常简单的问题可以直接写出相应的C++ 程序之外(在值得使用计算机解决的应用问题中这种情况并不多),一般都应该采用第 2单元中介绍的“逐步求精”的结构化程序设计方法来编程
第 1 单元 Hello,C++! - 3 - 输出数据:The maximum common divisor is 6. 分 析: 可以看出, 该程序的主体部分几乎与原算法完全相同, 只是增加了一些 C++ 语言特有的内容。 程序的第 1 行是注解。注解以“//”开头, 直到该行的末尾,用于说明或解释程序段的 功能、变量的作用以及程序员认为应该向程序阅读者说明的任何内容。可以看到, 在该程序 中还有一些注解, 用于说明程序的结构。在将C++程序编译成目标代码时所有的注解行都会 被忽略掉, 因此即使使用了很多注解也不会影响目标码的效率。恰当地应用注解可以使程序 清晰易懂、便于调试, 便于程序员之间的交流与协作, 因此在自己编写的每个程序中都使用 精心撰写的注解是一个良好的编程习惯。C++中还有一种注解格式, 可参看 1.5.2。 第 2 行是编译预处理, 有关内容将在 1.5.5 节介绍。 从第 3 行到最后一行, 是主函数。主函数是该程序的主体部分, 由其声明部分 void main() 和用一对花括号{}括起来的函数体构成。在函数体内, 除了注解行以外, 还有语句。C++ 的语句可分为声明语句和执行语句,声明语句用于声明程序中使用的变量、函数等的类型和 参数,执行语句实际执行某功能。第 5 行就是一个类型声明语句 int p, q, r; 声明在该程序中使用了 3 个整型变量。关于类型和变量等概念, 将在第 3 单元中详细介绍。 就一般的计算机程序而言, 总是要包括三个基本内容:数据输入、计算和输出。 该程序的输入部分首先在计算机屏幕上显示一行提示信息(第 7 行): Please input two integer numbers: 然后等待使用者由键盘输入两个整数。用户输入的两个正整数由语句 cin >> p >> q; 分别存入变量 p 和 q。 程序下面的部分就是欧几里德算法的具体实现了。可以看出, C++程序类似自然语言, 只 是结构更加严谨,对照前面的算法不难理解。 程序中的最后一个语句是输出语句, 将计算结果显示在计算机屏幕上。 1.3 输入、编译、调试和运行一个 C++程序 C++是一种编译语言,C++源程序需要经过编译、连接,生成可执行文件后方可运行。 使用 C++开发一个应用程序大致要经过以下步骤: 1.首先要根据实际问题确定编程的思路,包括选用适当的数学模型。这方面的内容其实 也是各应用学科的主要研究领域之一; 2.根据前述思路或数学模型编写程序。除了非常简单的问题可以直接写出相应的C++ 程序之外(在值得使用计算机解决的应用问题中这种情况并不多),一般都应该采用第 2 单元中介绍的“逐步求精”的结构化程序设计方法来编程;
第1单元Hel,C++ 3.编辑源程序。首先应将源程序输入计算机,这项工作可以通过任何一种文本编辑器(如 Visual c艹+集成环境中的文本编辑器)完成。输入的源程序一般以文件的形式存放在 磁盘上(后缀为CPP)。 4.编译和连接。在设计高级语言(包括C++)时充分考虑了人(程序员)的需要,源程 序很接近人类自然语言。因此,需要将源程序转换为计算机可直接执行的指令。就 C+而言,这项工作又可分为称为编译和连接的两个步骤,编译阶段将源程序转换成 目标文件(后缀为OBJ),连接阶段将目标文件连接成可执行文件(后缀为EXE) 5.反复上机调试程序,直到改正了所有的编译错误和运行错误。在调试过程中应该精心 选择典型数据进行试算,避免因调试数据不能反映实际数据的特征而引起计算偏差 和运行错误; 6.运行。如果是自用程序,在调试通过以后即可使用实际数据运行程序,得到计算结果 如果是商品软件或受委托开发的软件,则运行由用户实施 应该说明的是,如果要利用C艹+开发一个大型应用系统,例如管理信息系统、数据库 应用系统、计算机辅助教学系统或者实时控制系统等,一般要比编写一个数值计算方面的应 用程序复杂得多,上面介绍的开发步骤就显得过于简单了。这时要遵循软件工程的方法进行 应用系统开发,例如采用面向对象的设计开发技术。这方面的内容已经超出本课程的范围, 有兴趣的读者可以参看有关软件工程方面的书籍和资料 自学内容 14C++语言的历史、特点、用途和发展 早期出现的高级程序设计语言大都面向某个具体的应用领域,如用于科学计算的 FORTRAN和 algol60、用于商业数据处理的 COBOL以及用于人工智能编程的LSP等等。 但是对于最基本的系统软件,如操作系统和各种高级语言的编译程序来说,却缺乏一种合适 的高级程序设计语言,因此通常还是直接使用机器指令代码或者汇编语言编写程序,效率很 低且易于出错,根本无法适应规模越来越大的系统软件开发。究其原因,是当时的计算机硬 件的基本性能,如处理速度、存储容量等相对来说还不很高,因此系统软件的主导设计思想 是充分发挥系统硬件的能力,尽量提高软件的运行效率:而当时现有的程序设计语言与计算 机硬件的实际情况脱节,经编译后生成的目标代码冗余量大、运行速度慢,也不适于用来编 写作为应用软件的基础的操作系统、编译程序等系统软件。 70年代初,随着半导体集成电路技术的发展,计算机硬件的性能有了很大的提高,出现 了每秒运算次数达百万次以上的大型计算机。为这种计算机配备的各种软件的规模也越来越 大,结构越来越复杂,其生产组织和管理机制与极端注重代码运行效率的、以程序员个体劳 动为基础的传统编程方式之间产生了尖锐的矛盾,终于导致了所谓的“软件危机”。其直接 结果是出现了程序设计思想的革命,一改重视发挥机器效率的旧程序设计方法为重视人的 因素,强调充分发挥程序员的效率,强调程序员之间合作交流的能力,即以提高程序可读性 为主要目标的结构化程序设计方法
第 1 单元 Hello,C++! - 4 - 3.编辑源程序。首先应将源程序输入计算机,这项工作可以通过任何一种文本编辑器(如 Visual C++集成环境中的文本编辑器)完成。输入的源程序一般以文件的形式存放在 磁盘上(后缀为 CPP)。 4.编译和连接。在设计高级语言(包括 C++)时充分考虑了人(程序员)的需要,源程 序很接近人类自然语言。因此,需要将源程序转换为计算机可直接执行的指令。就 C++而言,这项工作又可分为称为编译和连接的两个步骤,编译阶段将源程序转换成 目标文件(后缀为 OBJ),连接阶段将目标文件连接成可执行文件(后缀为 EXE)。 5.反复上机调试程序, 直到改正了所有的编译错误和运行错误。在调试过程中应该精心 选择典型数据进行试算, 避免因调试数据不能反映实际数据的特征而引起计算偏差 和运行错误; 6.运行。如果是自用程序,在调试通过以后即可使用实际数据运行程序, 得到计算结果; 如果是商品软件或受委托开发的软件,则运行由用户实施。 应该说明的是, 如果要利用C++ 开发一个大型应用系统, 例如管理信息系统、数据库 应用系统、计算机辅助教学系统或者实时控制系统等, 一般要比编写一个数值计算方面的应 用程序复杂得多, 上面介绍的开发步骤就显得过于简单了。这时要遵循软件工程的方法进行 应用系统开发, 例如采用面向对象的设计开发技术。这方面的内容已经超出本课程的范围, 有兴趣的读者可以参看有关软件工程方面的书籍和资料。 自学内容 1.4 C++语言的历史、特点、用途和发展 早期出现的高级程序设计语言大都面向某个具体的应用领域, 如用于科学计算的 FORTRAN 和 Algol60、用于商业数据处理的 COBOL 以及用于人工智能编程的 LISP 等等。 但是对于最基本的系统软件, 如操作系统和各种高级语言的编译程序来说, 却缺乏一种合适 的高级程序设计语言, 因此通常还是直接使用机器指令代码或者汇编语言编写程序,效率很 低且易于出错,根本无法适应规模越来越大的系统软件开发。究其原因, 是当时的计算机硬 件的基本性能, 如处理速度、存储容量等相对来说还不很高, 因此系统软件的主导设计思想 是充分发挥系统硬件的能力, 尽量提高软件的运行效率;而当时现有的程序设计语言与计算 机硬件的实际情况脱节, 经编译后生成的目标代码冗余量大、运行速度慢, 也不适于用来编 写作为应用软件的基础的操作系统、编译程序等系统软件。 70 年代初, 随着半导体集成电路技术的发展, 计算机硬件的性能有了很大的提高, 出现 了每秒运算次数达百万次以上的大型计算机。为这种计算机配备的各种软件的规模也越来越 大, 结构越来越复杂, 其生产组织和管理机制与极端注重代码运行效率的、以程序员个体劳 动为基础的传统编程方式之间产生了尖锐的矛盾, 终于导致了所谓的“软件危机”。其直接 结果是出现了程序设计思想的革命, 一改重视发挥机器效率的旧程序设计方法为重视人的 因素, 强调充分发挥程序员的效率, 强调程序员之间合作交流的能力, 即以提高程序可读性 为主要目标的结构化程序设计方法
第1单元Hel,C++ C语言正是在这种时代背景下诞生的 1969年,美国贝尔实验室的 Ken Thompson为 DEC PDP7计算机设计了一个操作系统 软件,这就是最早的UNIX。接着,他又根据剑桥大学的 Martin richards设计的BCPL语言 为UNIX设计了一种便于编写系统软件的语言,命名为B。B语言是一种无类型的语言,直 接对机器字操作,这一点和后来的C语言有很大不同。作为系统软件编程语言的第一个应用 ken Thompson使用B语言重写了其自身的解释程序。 1972-1973年间,同在贝尔实验室的 Denis Ritchie改造了B语言,为其添加了数据类型 的概念,并将原来的解释程序改写为可以直接生成机器代码的编译程序,然后将其命名为 C。1973年, Ken Thompson小组在PDP-11机上用C重新改写了UNX的内核。与此同时,C 语言的编译程序也被移植到IBM360/370、 Honeywell 1l以及ⅤAX-11/80等多种计算机上 迅速成为应用最广泛的系统程序设计语言。 然而,C语言也存在一些缺陷,例如类型检查机制相对较弱:缺少支持代码重用的语言 结构等,造成用C语言开发大程序比较困难 为了克服C语言存在的缺点,并保持C语言简洁、高效的特点,贝尔实验室的 Bjarne Stroustrup博士及其同事开始对C语言进行改进和扩充,将“类”的概念引入了C语言,构 成了最早的C++语言(1983)。后来, Stroustrup和他的同事们又为C++引进了运算符重载 引用、虚函数等许多特性,并使之更加精炼,于1989年推出了AT&TC++20版。随后美国 标准化协会以AT&TC++2.0为基础,制定了 ANSI C++标准。各软件商推出的C++编译器 都支持该标准,并有不同程度的拓展 C++支持面向对象的程序设计方法(参看第7单元),特别适合于中型和大型的软件开 发项目,从开发时间、费用到软件的可重用性、可扩充性、可维护性和可靠性等方面,C+ 均具有很大的优越性。同时,C艹又是C语言的一个超集,这就使得许多C代码不经修改 就可被C++编译器编译通过。 早期的C+编译器称为 Cfront,实际上只是一个预处理程序,负责将C++程序转换为C 程序,然后再由C语言编程序继续编译。后来也出现了可以直接将C++程序编译为目标代码 的C艹+编译程序, 随着 Windows操作系统的出现,应用程序的外观和结构发生了巨大的变化,程序设计 的环境也得到了很大的改善。为了适应 Windows编程,各软件厂商纷纷推出了新型C++编 译器, Microsoft公司的 Visual c++就是其中的矫矫者。Ⅴ isual C++并不是一个单纯的编译器 而是一整套用于软件开发的集成环境(IDE),其中包括了文本编辑、编译连接、调试、可 视化界面设计和完备的在线帮助,甚至可直接通过 Internet与 Microsoft公司的站点连接, 得到技术支持和产品更新升级 15C++程序的基本要素 151标识符、关键词和标点符号 标识符是程序中变量、类型、函数和标号的名称。标识符由字母、数字和下划线“”组 成,第一个字符不能是数字。与 FORTRAN和 BASIC等程序设计语言不同,在C++的编译 器把大写和小写字母当作不同的字符。这个特征称为“大小写敏感的”。各种C++编译器
第 1 单元 Hello,C++! - 5 - C语言正是在这种时代背景下诞生的。 1969 年, 美国贝尔实验室的 Ken Thompson 为 DEC PDP-7 计算机设计了一个操作系统 软件, 这就是最早的 UNIX。接着, 他又根据剑桥大学的 Martin Richards 设计的 BCPL 语言 为 UNIX 设计了一种便于编写系统软件的语言, 命名为B。B语言是一种无类型的语言, 直 接对机器字操作, 这一点和后来的C语言有很大不同。作为系统软件编程语言的第一个应用, ken Thompson 使用B语言重写了其自身的解释程序。 1972-1973 年间, 同在贝尔实验室的 Denis Ritchie 改造了B语言, 为其添加了数据类型 的概念, 并将原来的解释程序改写为可以直接生成机器代码的编译程序, 然后将其命名为 C。1973 年, Ken Thompson 小组在 PDP-11 机上用C重新改写了 UNIX 的内核。与此同时, C 语言的编译程序也被移植到 IBM 360/370、Honeywell 11 以及 VAX-11/780 等多种计算机上, 迅速成为应用最广泛的系统程序设计语言。 然而,C 语言也存在一些缺陷,例如类型检查机制相对较弱;缺少支持代码重用的语言 结构等,造成用 C 语言开发大程序比较困难。 为了克服 C 语言存在的缺点,并保持 C 语言简洁、高效的特点,贝尔实验室的 Bjarne Stroustrup 博士及其同事开始对 C 语言进行改进和扩充,将“类”的概念引入了 C 语言,构 成了最早的 C++语言(1983)。后来,Stroustrup 和他的同事们又为 C++引进了运算符重载、 引用、虚函数等许多特性,并使之更加精炼,于 1989 年推出了 AT&T C++2.0 版。随后美国 标准化协会以 AT&T C++2.0 为基础,制定了 ANSI C++标准。各软件商推出的 C++编译器 都支持该标准,并有不同程度的拓展。 C++支持面向对象的程序设计方法(参看第 7 单元),特别适合于中型和大型的软件开 发项目,从开发时间、费用到软件的可重用性、可扩充性、可维护性和可靠性等方面,C++ 均具有很大的优越性。同时,C++又是 C 语言的一个超集,这就使得许多 C 代码不经修改 就可被 C++编译器编译通过。 早期的C++编译器称为 Cfront, 实际上只是一个预处理程序, 负责将C++程序转换为C 程序, 然后再由C语言编程序继续编译。后来也出现了可以直接将C++程序编译为目标代码 的C++编译程序。 随着 Windows 操作系统的出现,应用程序的外观和结构发生了巨大的变化,程序设计 的环境也得到了很大的改善。为了适应 Windows 编程,各软件厂商纷纷推出了新型 C++编 译器,Microsoft 公司的 Visual C++就是其中的矫矫者。Visual C++并不是一个单纯的编译器, 而是一整套用于软件开发的集成环境(IDE),其中包括了文本编辑、编译连接、调试、可 视化界面设计和完备的在线帮助,甚至可直接通过 Internet 与 Microsoft 公司的站点连接,以 得到技术支持和产品更新升级。 1.5 C++程序的基本要素 1.5.1 标识符、关键词和标点符号 标识符是程序中变量、类型、函数和标号的名称。标识符由字母、数字和下划线“_”组 成,第一个字符不能是数字。与 FORTRAN 和 BASIC 等程序设计语言不同,在 C++的编译 器把大写和小写字母当作不同的字符。这个特征称为“大小写敏感的”。各种C++编译器
第1单元Hel,C++ 对在标识符中最多可以使用多少个字符的规定各不相同,ANSI标准规定编译器应识别标识 符的前6个字符,而Ⅴ isual C++编译器允许在程序中使用长达247个字符的标识符!在标识 符中恰当运用下划线,大、小写字母混用以及使用较长的名字都有助于提高程序的可读性。 例如在一个人事管理软件中,用函数名 read employee file()(读职工档案)、变量名 Employee Count(职工人数)等就要比用函数名f()、变量名n等清楚得多。 在 Visual C++中,有下列关键词 asm, auto, bad cast, bad typed, bool, break, case, catch, char, class, const except, extern, explicit false, finally, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public, register reinterpret cast, return, short, signed, sizeof, static, static cast, struct, switch, template, this, throw, try, type info, typedef, typeid, union, unsigned, using, virtual. void volatile. while. xalloc 用于表示C++本身的特定成份,具有相应的语义。程序员在命名变量、数组和函数的名称时, 不能使用这些标识符 另外,C++还使用了下列12个标识符作为编译预处理的命令单词 define, elif, else, endif, error, if, ifdef, ifndef, include, line, progma, undef 并赋予了特定含义。程序员在命名变量、数组和函数时也不要使用它们。 在C++字符集中标点和特殊字符有各种用途,从组织程序文本到定义编译器或编译的程 序的执行功能。有些标点符号也是运算符(参见第3单元“基本数据类型与表达式”中的有 关内容),编译器可从上下文确定它们的用途。C++的标点有 这些字符在C++中均具有特定含义。 15.2注解 C艹+的注解有两种形式,一种以两个斜杠符“∥”起头,直至行末。一种是用斜线星号 组合“/”和“*/”括起的任意文字(但不能再包含“*”和“*/”,即注解不能嵌套), 多用于注解篇幅多于一行的情况。注解可以出现在空白字符允许出现的任何地方,编译器把 注解作为一个空白字符处理 恰当使用注解可以使程序容易阅读 15.3源程序 份C++源程序由一个或多个源代码文件构成。C++源程序中包括命令、编译指示、声 明、定义、注解和函数等内容。为了使程序的结构清晰,通常的做法是在一个源代码文件中 放置变量、类型、宏和类等的声明(称为头文件,后缀为H),然后在另一个源代码文件中 引用这些变量(称为源程序文件,后缀为CPP)。采用这种方式编写的程序,很容易查找和 修改各类声明
第 1 单元 Hello,C++! - 6 - 对在标识符中最多可以使用多少个字符的规定各不相同, ANSI 标准规定编译器应识别标识 符的前 6 个字符, 而 Visual C++编译器允许在程序中使用长达 247 个字符的标识符!在标识 符中恰当运用下划线, 大、小写字母混用以及使用较长的名字都有助于提高程序的可读性。 例如在一个人事管理软件中, 用函数名 read_employee_file ( ) (读职工档案)、变量名 EmployeeCount (职工人数) 等就要比用函数名 f ( )、变量名 n 等清楚得多。 在 Visual C++中,有下列关键词: asm, auto, bad_cast, bad_typed, bool, break, case, catch, char, class, const, const_cast, continue, default, delete, do, double, dynamic_cast, else, enum, except, extern, explicit, false, finally, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_cast, struct, switch, template, this, throw, try, type_info, typedef, typeid, union, unsigned, using, virtual, void, volatile, while, xalloc 用于表示C++本身的特定成份, 具有相应的语义。程序员在命名变量、数组和函数的名称时, 不能使用这些标识符。 另外, C++还使用了下列 12 个标识符作为编译预处理的命令单词: define, elif, else, endif, error, if, ifdef, ifndef, include, line, progma, undef 并赋予了特定含义。程序员在命名变量、数组和函数时也不要使用它们。 在 C++字符集中标点和特殊字符有各种用途,从组织程序文本到定义编译器或编译的程 序的执行功能。有些标点符号也是运算符 (参见第 3 单元“基本数据类型与表达式”中的有 关内容),编译器可从上下文确定它们的用途。C++的标点有 [ ] ( ) { } * & , : = ; ... # 这些字符在 C++中均具有特定含义。 1.5.2 注解 C++的注解有两种形式,一种以两个斜杠符“//”起头, 直至行末。一种是用斜线星号 组合 “/*”和“*/”括起的任意文字(但不能再包含“/*”和“*/”,即注解不能嵌套), 多用于注解篇幅多于一行的情况。注解可以出现在空白字符允许出现的任何地方,编译器把 注解作为一个空白字符处理。 恰当使用注解可以使程序容易阅读。 1.5.3 源程序 一份 C++源程序由一个或多个源代码文件构成。C++源程序中包括命令、编译指示、声 明、定义、注解和函数等内容。为了使程序的结构清晰,通常的做法是在一个源代码文件中 放置变量、类型、宏和类等的声明(称为头文件,后缀为.H),然后在另一个源代码文件中 引用这些变量(称为源程序文件,后缀为.CPP)。采用这种方式编写的程序,很容易查找和 修改各类声明
第1单元Hel,C++ 15.4编译预处理 将程序编译的过程分为预处理和正式编译两个步骤是C++的一大特点。在编译C++程序 时,编译器中的预处理模块首先根据预处理命令对源程序进行适当的加工,然后才进行正式 编译。 预处理命令均以符号“#”开头,且在一行中只能书写一条预处理命令(过长的预处理命 令可以在使用续行标志“\”后续写在下一行上),且结束时不能使用语句结束符(分号“;”)。 C++中有3种主要编译预处理命令:宏定义、文件包含和条件编译。下面先介绍其中 的前两种,条件编译将在第4单元中介绍。 1.宏定义 无参宏定义通常用来定义符号常数,其格式为: # define是一个标识符。为了和变量有所区别,习惯上在为无参宏起名时只使用大写字 母。例如 #define pi 3. 14159 该宏定义命令为常量3.14159起了一个符号化的名字PI。这样,在该宏定义命令之后的程 序中,均可以使用符号常数PI表示数值3.14159,例如 PlEkrskr 使用符号常数的程序可读性好,易于阅读理解。另外,将程序中的常量用符号常数表示 也有利于程序的调试和修改。例如,程序中分别使用了两个符号常数,它们的值碰巧相同 #define MaX number #define LIne le 以后如果发现需要将其中的一个修改为其他数值,则只须修改上面的宏定义即可。但是如果 不使用宏定义,则需逐个查出程序中所有数值80,一一判断是否是需要修改的那一个。不 但费事,而且容易出错。 应该说明的是用宏命令定义的符号常数不是变量,象 LINE LEN =100. 这样的用法是错误的。其实,宏定义命令的真正含义是要求编译程序在对源程序进行预处理 时,将源程序中所有的符号名“ MAX NUMBER”和“ LINE LEN”(但不包括出现在注解与字符 串中的“ MAX NUMBER”和“ LINE LEN”)分别替换为字符序列“80”。因此到了正式编译时, 符号名“ LINE LEN”已经不存在了,语句“ LINE LEN=100;”已经变为“80=100;”,由 于赋值运算符的左边不是变量而是一个常数80,显然这是一个错误的赋值表达式语句 在定义宏时还可以加上参数,这就构成了带参数的宏 # define(<参数表》)<带有参数的替换序列〉 例如
第 1 单元 Hello,C++! - 7 - 1.5.4 编译预处理 将程序编译的过程分为预处理和正式编译两个步骤是C++的一大特点。在编译C++程序 时, 编译器中的预处理模块首先根据预处理命令对源程序进行适当的加工, 然后才进行正式 编译。 预处理命令均以符号“#”开头,且在一行中只能书写一条预处理命令 (过长的预处理命 令可以在使用续行标志“\”后续写在下一行上), 且结束时不能使用语句结束符(分号“;”)。 C++中有 3 种主要编译预处理命令:宏定义、文件包含和条件编译。下面先介绍其中 的前两种,条件编译将在第 4 单元中介绍。 1. 宏定义 无参宏定义通常用来定义符号常数, 其格式为: #define 其中是一个标识符。为了和变量有所区别, 习惯上在为无参宏起名时只使用大写字 母。例如: #define PI 3.14159 该宏定义命令为常量 3.14159 起了一个符号化的名字 PI。这样,在该宏定义命令之后的程 序中,均可以使用符号常数 PI 表示数值 3.14159,例如: s = PI*r*r; 使用符号常数的程序可读性好, 易于阅读理解。另外, 将程序中的常量用符号常数表示 也有利于程序的调试和修改。例如, 程序中分别使用了两个符号常数, 它们的值碰巧相同: #define MAX_NUMBER 80 #define LINE_LEN 80 以后如果发现需要将其中的一个修改为其他数值, 则只须修改上面的宏定义即可。但是如果 不使用宏定义, 则需逐个查出程序中所有数值 80, 一一判断是否是需要修改的那一个。不 但费事, 而且容易出错。 应该说明的是用宏命令定义的符号常数不是变量, 象 LINE_LEN = 100; 这样的用法是错误的。其实,宏定义命令的真正含义是要求编译程序在对源程序进行预处理 时, 将源程序中所有的符号名“MAX_NUMBER”和“LINE_LEN” (但不包括出现在注解与字符 串中的“MAX_NUMBER”和“LINE_LEN”) 分别替换为字符序列“80”。因此到了正式编译时, 符号名“LINE_LEN”已经不存在了,语句“LINE_LEN = 100;”已经变为“80 = 100;”, 由 于赋值运算符的左边不是变量而是一个常数 80, 显然这是一个错误的赋值表达式语句。 在定义宏时还可以加上参数, 这就构成了带参数的宏: #define () 例如
第1单元Hel,C++ #define max(a, b)((a)>(b)?(a): (b)) 带参数的宏的使用用法颇象函数。例如 x max(x, 10) 即如果变量x的值小于10,则将常数10赋给x,否则x的值保持不变。实际上,这个带参数 的宏的确切含义为,通知编译程序中的预处理模块在对应用程序进行处理时遇到形如max 的串时要进行转换,在转换时还要对参数进行代换处理。上述宏定义经过转换后会变为 x=((x)>(10)?(x):(10) 在利用宏命令定义带参数的宏时,要注意宏名与括号之间不能有空格,且所有的参数均 应出现于右边的替换序列中 虽然带参数的宏很象函数,但这两者之间的区别是很明显的。编译程序在处理带参数的 宏时,并不是用实参的值进行代入计算,而只是简单地将替换序列中的参数用相应的实参原 样替换(按参数书写位置,从左到右一一对应)。因此,在书写带参数的宏时,要防止由于使 用表达式参数带来的错误。例如定义了一个用于计算圆面积的宏 #define circle area (r) r*r*3. 14159 在计算 s- CIr (x+16) 就会出问题。将参数x+16代入上述宏定义中,有 x+16*x+16*3.14159 就会发现运算的顺序显然有错误。如果重新定义这个宏 #define circle area(r)((r)* (r)=3. 14159) 就没有问题了。总而言之,在定义带参数的宏时应将每个参数和整个替换序列都用括号括起 来,以防止可能的计算错误[注1] 取消宏定义命令# undef用于撤消对一个符号名的定义。例如 #define debug 1 //在本程序段落中定义了一个值为1的符号常数 DEBUG #undef dEBUG 如果没有# undef命令,则宏定义起作用的范围为自# define命令起至该源程序文件末 2.文件包含 编译预处理命令中的文件包含命令的功能是将另一段C++源程序文件嵌入到正在进行 预处理的源程序中的相应位置上。文件包含命令的格式为 # include<文件名
第 1 单元 Hello,C++! - 8 - #define max(a,b) ((a)>(b)?(a):(b)) 带参数的宏的使用用法颇象函数。例如: x = max(x,10); 即如果变量 x 的值小于 10,则将常数 10 赋给 x, 否则 x 的值保持不变。实际上, 这个带参数 的宏的确切含义为, 通知编译程序中的预处理模块在对应用程序进行处理时遇到形如 max() 的串时要进行转换, 在转换时还要对参数进行代换处理。上述宏定义经过转换后会变为 x = ((x)>(10)?(x):(10)); 在利用宏命令定义带参数的宏时, 要注意宏名与括号之间不能有空格, 且所有的参数均 应出现于右边的替换序列中。 虽然带参数的宏很象函数, 但这两者之间的区别是很明显的。编译程序在处理带参数的 宏时, 并不是用实参的值进行代入计算, 而只是简单地将替换序列中的参数用相应的实参原 样替换 (按参数书写位置,从左到右一一对应)。因此, 在书写带参数的宏时, 要防止由于使 用表达式参数带来的错误。例如定义了一个用于计算圆面积的宏: #define circle_area(r) r*r*3.14159 在计算 s = circle_area(x+16) 就会出问题。将参数 x+16 代入上述宏定义中,有 s = x+16*x+16*3.14159 就会发现运算的顺序显然有错误。如果重新定义这个宏: #define circle_area(r) ((r)*(r)*3.14159) 就没有问题了。总而言之, 在定义带参数的宏时应将每个参数和整个替换序列都用括号括起 来, 以防止可能的计算错误[注 1]。 取消宏定义命令#undef 用于撤消对一个符号名的定义。例如 #define DEBUG 1 // 在本程序段落中定义了一个值为 1 的符号常数 DEBUG #undef DEBUG 如果没有#undef 命令,则宏定义起作用的范围为自#define 命令起至该源程序文件末 尾。 2. 文件包含 编译预处理命令中的文件包含命令的功能是将另一段C++源程序文件嵌入到正在进行 预处理的源程序中的相应位置上。文件包含命令的格式为: #include
第1单元Hel,C++ 或者 # include"文件名 其中“文件名”是指被嵌入的C++源程序文件的文件名,必须用双引号或者尖括号(实际上 是一个小于号和一个大于号)括起来。通过使用不同的括号可以通知预处理程序在查找嵌入 文件时采用不同的策略。如果使用了尖括号,那么预处理程序在系统规定的目录(通常是在 系统的 include子目录)中査找该文件。如果使用双引号,那么编译预处理程序首先在当前 目录中查找嵌入文件,如果找不到则再去由操作系统的path命令所设置的各个目录中去查 找。如果仍 然没有查找 myprg. C 源程序文件 到,最后再abc s#include "abc. h myprg ob 去上述规定被嵌入的文件 编译|目标文件 的目录 lude 子目录)中 查找 原来的 源程序文件 和用文件包 含命令嵌入 图1-1文件包含 的源程序文 件在逻辑上被看成是同一个文件,经过编译后生成一个目标文件,如图1-1所示。 155输入与输出 程序通常会要求用户提供一些信息(如数据),这一过程被称为程序的输入。程序通常 总是要向用户发出一些信息(如计算结果等),这一过程被称为程序的输出。C++程序的输 入操作可由cin对象来完成,而输出操作则可由cout对象来完成 cin的基本用法为 cin>>V1>>V2>>..>>Vn 其中“>”称做提取运算符,V,V2vn都是变量。这个语句的意思是,程序暂时中止执 行,等待用户从键盘上输入数据。用户输入了所有的数据后,应以回车键表示输入结束,程 序将用户键入的数据存入各变量中,并继续执行下面的语句。例如例1-1中的第8行: cin > 就是要求用户分别为变量p和q各输入一个数据。在输入时,应注意用空格或tahb键将所输 入的数据分隔开。 应说明的是,当用户响应cin的要求输入数据时,必须注意所输入数据的类型(C++的 数据类型将在第3单元中介绍)应与接受该数据之变量的类型相匹配,否则输入操作将会失 败或者得到的将是一个错误的数据
第 1 单元 Hello,C++! - 9 - 或者 #include "文件名" 其中“文件名”是指被嵌入的C++源程序文件的文件名, 必须用双引号或者尖括号(实际上 是一个小于号和一个大于号)括起来。通过使用不同的括号可以通知预处理程序在查找嵌入 文件时采用不同的策略。如果使用了尖括号, 那么预处理程序在系统规定的目录(通常是在 系统的 include 子目录)中查找该文件。如果使用双引号, 那么编译预处理程序首先在当前 目录中查找嵌入文件, 如果找不到则再去由操作系统的 path 命令所设置的各个目录中去查 找。如果仍 然没有查找 到,最后再 去上述规定 的目录 ( include 子目录)中 查找。 原来的 源程序文件 和用文件包 含命令嵌入 的源程序文 件在逻辑上被看成是同一个文件, 经过编译后生成一个目标文件, 如图 1-1 所示。 1.5.5 输入与输出 程序通常会要求用户提供一些信息(如数据),这一过程被称为程序的输入。程序通常 总是要向用户发出一些信息(如计算结果等),这一过程被称为程序的输出。C++程序的输 入操作可由 cin 对象来完成,而输出操作则可由 cout 对象来完成。 cin 的基本用法为: cin>>V1>>V2>>…>>Vn; 其中“>>”称做提取运算符,V1,V2,…,Vn 都是变量。这个语句的意思是,程序暂时中止执 行,等待用户从键盘上输入数据。用户输入了所有的数据后,应以回车键表示输入结束,程 序将用户键入的数据存入各变量中,并继续执行下面的语句。例如例 1-1 中的第 8 行: cin >> p >> q; 就是要求用户分别为变量 p 和 q 各输入一个数据。在输入时,应注意用空格或 tab 键将所输 入的数据分隔开。 应说明的是,当用户响应 cin 的要求输入数据时,必须注意所输入数据的类型(C++的 数据类型将在第 3 单元中介绍)应与接受该数据之变量的类型相匹配,否则输入操作将会失 败或者得到的将是一个错误的数据。 abc.h 被嵌入的文件 myprg.c 源程序文件 #include "abc.h" ... ... myprg.obj 目标文件 图1-1 文件包含 编 译
第1单元Hell,C++! cout的基本用法具有如下的一般形式: cout<<E1<<E2<<.<<Em; 其中“<<”称做插入运算符,E1,F2,,Em都是表达式(第3单元中介绍)。这个语句 的意思是,将各表达式的值输出(显示)到屏幕上当前光标位置处。在输出时,要注意恰当 使用字符串和新行符end,提高输出信息的可读性 调试技术 16 Visual o++的集成开发环境 Visual c++软件包包含了许多独立的组件,如编辑器、编译器、链接器、实用程序生成 器、调试器,以及各种各样为开发 Windows环境下的C/C++程序而设计的工具。其中最重 要的是一个名为 Developer Studio的集成开发环境。 Developer Studio把所有的 Visual c++工 具结合在一起,集成为一个由窗口、对话框、菜单、工具栏、快捷键及宏组成的和谐系统, 通过该集成环境,程序员可以观察和控制整个开发进程。 图1-2显示了一个典型的 Developer Studio主窗口。 5 从图1-2中可以看出, Developer omor daner 整型变量p, Studio主窗口可以分为几个部分:窗 正整数 口顶部是菜单和工具栏,左面的一个 子窗口是工作区窗口,工作区的右面 是编辑子窗口。最下面是输出子窗 不等于B。重复进行下列计算 口。值得注意的是,上述各种部件, befiquralian: uIn.]2 DEbug 包括子窗口、菜单栏和工具栏的位置Fmmm 不是一成不变的,可以根据个人的喜 DEbug Xfind in ties 1Xfind in Faes 2 X ResuHs.ll 好重新安排。 图1-2典型的 Developer Studio主窗口 16.11菜单和工具栏 Developer Studio中有一个 Menu bar(菜单栏,通常停靠在开发环境窗口的顶部),其 中的菜单项有File(文件处理)、Edit(编辑功能)、Ⅴiew(査看)、 Insert(插入)、 Project (项目管理)、Buld(编译)、 Tools(工具)、 Window(窗口)和Help(帮助)等,分 别对应一个下拉子菜单 除菜单栏外,开发环境中还有几个工具栏,一般均放在开发环境的顶部,菜单栏的下方 如 Standard(标准工具栏,用于文件管理、编辑和査看等), Wizard Bar(向导工具栏)和 Build mini Bar(建立工具栏,用于编译、连接等)。工具栏上有常用命令的图标。一般来说, 工具栏上的命令在菜单中均有对应选项,但工具栏使用更方便,只要用鼠标左键点击工具栏 中的相应图标即可调用相应的功能。 开发环境的各种菜单栏和工具栏均为停靠式,可以用鼠标拖动改变它们的位置,也可使
第 1 单元 Hello,C++! - 10 - cout 的基本用法具有如下的一般形式: cout << E1 << E2 <<…<< Em; 其中“<<”称做插入运算符,E1,E2,…,Em 都是表达式(第 3 单元中介绍)。这个语句 的意思是,将各表达式的值输出(显示)到屏幕上当前光标位置处。在输出时,要注意恰当 使用字符串和新行符 endl,提高输出信息的可读性。 调试技术 1.6 Visual C++的集成开发环境 Visual C++软件包包含了许多独立的组件,如编辑器、编译器、链接器、实用程序生成 器、调试器,以及各种各样为开发 Windows 环境下的 C/C++程序而设计的工具。其中最重 要的是一个名为 Developer Studio 的集成开发环境。Developer Studio 把所有的 Visual C++工 具结合在一起,集成为一个由窗口、对话框、菜单、工具栏、快捷键及宏组成的和谐系统, 通过该集成环境,程序员可以观察和控制整个开发进程。 图 1-2 显 示 了 一 个 典 型 的 Developer Studio 主窗口。 从图 1-2 中可以看出,Developer Studio 主窗口可以分为几个部分:窗 口顶部是菜单和工具栏,左面的一个 子窗口是工作区窗口,工作区的右面 是编辑子窗口。最下面是输出子窗 口。值得注意的是,上述各种部件, 包括子窗口、菜单栏和工具栏的位置 不是一成不变的,可以根据个人的喜 好重新安排。 1.6.1 菜单和工具栏 Developer Studio 中有一个 Menu Bar(菜单栏,通常停靠在开发环境窗口的顶部),其 中的菜单项有 File (文件处理)、Edit(编辑功能)、View(查看)、Insert(插入)、Project (项目管理)、Build(编译)、Tools(工具)、Window(窗口)和 Help(帮助)等,分 别对应一个下拉子菜单。 除菜单栏外,开发环境中还有几个工具栏,一般均放在开发环境的顶部,菜单栏的下方, 如 Standard(标准工具栏,用于文件管理、编辑和查看等),Wizard Bar(向导工具栏)和 Build MiniBar(建立工具栏,用于编译、连接等)。工具栏上有常用命令的图标。一般来说, 工具栏上的命令在菜单中均有对应选项,但工具栏使用更方便,只要用鼠标左键点击工具栏 中的相应图标即可调用相应的功能。 开发环境的各种菜单栏和工具栏均为停靠式,可以用鼠标拖动改变它们的位置,也可使 图 1-2 典型的 Developer Studio 主窗口