1
第 1章 C++程序开发初步
2
第 1章 C++程序开发初步
最简单的 C++程序结构
函数
类与对象
C++程序开发过程与环境
3
程序设计中主要应用两大类模型
面向过程的模型
概括为,
数据结构 + 算法
面向对象的模型
认为世界是由一些对象( objects)组成的,
每一个对象包括属性和方法两部分;属性
是描述对象特征的一些数据或数据结构,
方法表明对象的变化或一个对象对其他对
象的作用,对象间通过消息传递进行通信
4
最简单的 C++程序结构
一个简单的 C++程序
运算符与表达式
数据类型
变量与常量
5
一个简单的 C++程序
# include <iostream.h>
int main ( )
{
int x,y,s;
// 定义 3个整数:两个代表加数,一个代表和
cout <<,输入两个整数:” ; // 给用户发出输入两个
数的提示
cin >> x >> y; // 输入两个整数到 x和 y
s = x + y; // 将 x和 y相加,送到 s中
cout <<,x + y =” // 输出提示
<< s // 输出 s的值
<< endl; // 换行,语句结束
return 0;
}
6
上例说明
C++的注释符有:, //”后面与, /*”和, */”之
间的
,;, 是 C++语句的结束符,表明一个语句
的结束
x”,,y”和, s”称为三个变量,是三个存储
数据的空间的名字
,cout”称为标准输出设备,通常指显示器
,cin”称为标准输入设备,通常指键盘
,endl”表示换行
,# include”称为文件包含
7
运算符与表达式
运算符是一种程序记号,它作用于操作数
而触发某种操作
由运算符和操作数组成的符号序列,就称
为表达式
8
最基本的运算符
算术运算符
赋值运算符
复合赋值运算符
9
运算符在表达式中的运算顺序
运算符的优先级别
运算符与操作数的结合方向
运算符的先后排列顺序
10
各种运算符间的优先级别和结合性
运算符 结合性 优先级别
单目减,- ← 高
低
双目算术
运算符,
* / →
+ - →
标准输入输出,>> << →
赋值,= ←
11
例 1.1.1
#include <iostream.h>
int main()
{
int x,y;
cout << "x = 3,y = 8,x *= y + 1:" << ( x = 3,y = 8,x *= y + 1 )<< endl;
cout << "x = 3,y = 8,x = x * y + 1:" << ( x = 3,y = 8,x = x * y + 1) <<
endl;
return 0;
}
12
++与 - -有两种使用形式
前缀形式,即它们在操作数前,如 ++x,- -x
后缀形式,即它们在操作数后,如 x++,x- -
++表达式与 - -表达式独立使用时,前缀形式
与后缀形式无区别,但它们在表达式中被
引用时,结果是不同的。
前缀形式是先增(减) 1,后被引用;后缀
形式是先被引用,后增(减) 1
13
例 1.1.2
# include <iostream.h>
int main( )
{
int x,y;
x = 5,y = x++; // 先引用后增 1
cout << "x=5,y=x++:" << y << ",x=" << x << endl;
x = 5,y = ++x ; // 先增 1后引用
cout << "x=5,y=++x:" << y << ",x=" << x << endl;
return 0;
}
14
数据类型
整型类型与实型类型
字符类型
字符串
算术数据的类型转换
sizeof 运算符
15
数据的规范化
为数据分配相应大小的存储空间;
确定数据值的范围;
确定数据的表示精度;
确定数据可以进行的运算种类。
16
最常用的数据类型的比较
数据类型
关键字
意义 存储
空间
表数精度
(有效数字 )
表数范围 运算类型
char 字符 8位 +,-,%
short 短整数 16位 -32768~32767 +,-,*
,/、
%
int 整数 32位 -2 147 483 648~2 147 483 647
float 单精度浮点 32位 7位 ?( 3.4× 10-38~3.4× 1038) +,-,*
,/、
% double 双精度浮点 64位 16位 ?( 2.23× 10-308~1.79× 10308)
long
doubl
e
长双精度 80位 18位 ± ( 3.37× 10-4932~1.18× 104932
)
17
整型类型与实型类型
整型就是不带有小数点的数据类型
C++还把整型数分为带符号和不带符号两
大类
实数一般用小数形式或科学记数法(指数
形式)书写
18
C++的转义字符序列
序 列 值 字符 功 能
\a 0X07 BEL 警告响铃
\b 0X08 BS 退格
\f 0X0C FF 走纸
\n 0X0A LF 换行
\r 0X0D CR 回车
\t 0X09 HT 水平制表
\v 0X0B VT 垂直制表
\\ 0X5c \ 反斜杠
\' 0X27 ' 单引号
\" 0X22 " 双引号
\? 0X3F? 问号
\o 整数 任意 0[L1]:最多为 3位的八进制数字串
\xH 整数 任意 H:十六进制数字串
19
字符串
字符串常量也称字符串文字或字符串,它
们是括在一对双撇号内的字符序列
字符串常量与字符型常量在内部存储上是
不同的
20
算术数据的类型转换
在表达式中,常常会发生数据类型的转换,
即将数据由一种类型转换成另一种类型
下面介绍这些类型转换规则。
常规转换
传送转换
用类型运算符进行显式转换
21
例 1.1.4
#include <iostream.h>
int main( )
{
short int a = -32768,b,i = 1234567890; //i溢出
unsigned short int ua = 32768,ub;
cout << "b=ua:" << (b=ua) << endl; //注意 ua对 int溢出
cout << "ub=a:" << (ub=a) << endl; //注意有符号负数向无符号数转换
cout << i;
}
22
sizeof 运算符
sizeof是一个单目运算符,用以计算操作数
在内存中占用的字节数。
它的操作数可以是以下两种情况,
括在圆括号中的类型标识符
一个表达式
sizeof 运算符具有最高优先级,最高优先
级中的运算符都是从右向左结合的
23
例 1.1.5
#include <iostream.h>
int main( ) // 该程序在 16位和 32位系统中的运行结果不同!
{
cout << "size of unsigned char:" << sizeof(unsigned char) << endl;
cout << "size of char:" << sizeof(char) << endl;
cout << "size of unsigned int:" << sizeof(unsigned int) << endl;
cout << "size of short int:" << sizeof(short int) << endl;
cout << "size of int:" << sizeof(int) << endl;
cout << "size of unsigned long:" << sizeof(unsigned long) << endl;
cout << "size of long:" << sizeof(long) << endl;
cout << "size of float:" << sizeof(float) << endl;
cout << "size of double:" << sizeof(double) << endl;
cout << "size of long double:" << sizeof(long double) << endl;
}
24
变量与常量
程序变量
字面常量与符号常量
25
程序变量
程序变量简称变量。变量有以下特点,
变量指称了程序中使用的一个被命名存储区域
(称程序实体),以存放可由程序修改的值,变
量在某一时刻的值称为变量值。
变量的名称为变量名。 C++规定变量名由如下三
种符号组成,
大小写字母 —— 可用于变量名的任何位置;
下划线 —— 可用于变量名的任何位置;
数字 —— 不能用于变量名的首部。
每个变量应属于一个特定的类型
26
例 1.1.6
# include <iostream.h>
int main( )
{
int i; // 声明 i为整型
i = 3; // 给变量 i赋值 3
cout << "The first\"i\" is," << i<< endl;
i = 5; // 给变量 i再赋值 5
cout << "The second \"i\" is," << i << endl;
cout << "Enter a number,";
cin >> i; // 由键盘给变量 i输入一个值
cout << "\nThe last \"i\" is," << i << endl;
}
27
字面常量与符号常量
常量可以是字面常量(也称直接常量)或
符号常量。前面使用的基本上都是字面常
量
下面介绍两种符号常量,
( 1)用 const定义的符号常量
( 2)用宏定义模拟符号常量
28
例 1.1.7
/*****************************
* 程序名,area_circum *
* 功 能:计算圆的面积与周长 *
******************************/
#include <iostream.h>
int main( )
{
float fArea,fCircum;
fArea = 3.1415926 * 2.0 * 2.0;
cout << "The area is:" << fArea << endl;
fCircum = 3.1415926 * 2.0 * 2.0;
cout << "The circum is:" << fCircum << endl;
}
29
用宏定义模拟符号常量
# include <iostream.h>
# define Pi 3.1415926 // 定义宏
# define r 2.0 // 定义宏
int main()
{
float fArea,fCircum;
fArea = Pi * r * r; // 引用宏
cout << "The area is," << fArea << endl;
fCircum = 2.0 * Pi * r; // 引用宏
cout << "The circumference is," << fCircum << endl;
}
30
函数
函数的意义与用法
函数定义与函数结构
函数原型与函数声明
函数调用与内联函数
传值调用与引用类型
库函数应用
31
函数的意义与用法
函数是 C++程序中组织过程的机制。它对
较大的程序比较有效。这里,主要介绍函
数的用法,因此仍然使用前面介绍过的求
圆的面积的例子,只不过用函数的形式来
描述
32
例 1.2.1
# include <iostream.h>
# define Pi 3.1415926
int main( )
{
float flR = 1.2,fArea;
float Area (float); // 函数声明
fArea = Area(flR); // 函数调用
cout <<"The area is," << fArea << endl;
}
float Area ( float fR) // 定义求圆面积的函数
{
return (Pi * fR * fR);
}
33
C++程序的一般结构
系统调用
返回系统
f1() f11()
{ ④ {
↓③ ↓⑤
main() ② f11(); ⑥ }
{ ↓⑦
↓① } f21()
f1(); ⑧ {
↓⑨ f2() 12 ↓13
f2(); 10 { }
↓21 ↓11 14
} f21(); f22()
20 ↓15 16 {
f22(); ↓17
↓19 18 }
}
34
函数定义与函数结构
一个 C++函数的定义由函数头与函数体两
部分组成,形式如下,
函数首部
{
函数体
}
35
函数首部
函数首部是函数的接口部分,其组成形式
如下,
类型名 函数名 ( 形式参数表列 )
函数类型规定为函数返回值的类型
函数名是函数的标识,它应是一个有效的
C++标识符
形式参数表列是括在园括号中的 0个或多
个以逗号分隔的形式参数
36
函数体
一个函数体是一个语句块,是用一对花括
号封装的语句序列。它描述了函数实现一
个功能的过程。它最后执行一个函数返回,
返回的作用是,
将流程从当前函数返回其上级(调用函
数);
撤销函数调用时为各参数及变量分配的内
存空间;
向调用函数返回顶多一个值
37
例 1.2.2
void Area ( float fR) // 定义求圆面积的函数
{
cout << "The area is,"<< (Pi * fR * fR) << endl;
return;
}
或
void Area ( float fR) // 定义求圆面积的函数
{
cout << "The area is,"<< (Pi * fR * fR) << endl;
return;
}
38
主函数 main()
main()函数是一个特殊的函数。它的名字
是固定的。它可看作是由操作系统调用的
一个函数。其返回值可以是 void型或 int型
(可以缺省)。当其返回值为 int型时,用 0
或非 0,告诉操作系统程序是否正常结束
39
例 1.2.3
# include <iostream.h>
main()
{
cout << "ok!";
return (0);
}
40
函数原型
函数原型也称函数模型,是由函数定义中
抽取出来的能代表函数应用特征的部分,
· 函数类型
· 函数名
· 参数个数及其类型
函数原型的形式为,
类型 函数名(参数类型1,参数类型
2,…,参数类型 n)
41
函数提前声明
当函数定义在前调用在后时,编译器在调
用函数之前,能从其定义中抽取函数原型
当函数调用在前定义在后时,要求程序员
在调用之前用函数原型对函数进行声明,
以便编译器从中得到函数原型所提供的有
关信息
函数声明中的参数名对编译器没有意义
42
函数调用与内联函数
函数调用的作用是,
· 用实参数(如例 1.2.1中的 nR)向形式参数
(如例 1.2.1中的 fR)传递数据;
· 中断现行(调用)函数,把流程转向(被
调用)函数的入口处,开始执行被调函数
在调用与返回过程中,需要付出一定的时间
与空间代价用于处理现场。当函数较小,又
反复使用时,处理现场的开销比重会急剧增
大。若把函数体嵌入函数调用处,便可以大
大提高运行速度,节省开销。内联函数就可
以自动实现这一功能
43
例 1.2.4
# include <iostream.h>
# define Pi 3.1415926
int main( )
{
float fR1 = 1.2,fR1 = 2.3,fArea;
float Area ( float); // 函数原型
声明
fArea = Area(fR1); // 函数调用 1
cout <<"The area is,"<< fArea << endl;
fArea = Area(fR2); // 函数调用 2
cout <<"The area is,"<< fArea << endl;
}
float Area ( float fR)
{
return (Pi * fR * fR);
}
44
例 1.2.5
# include <iostream.h>
# define Pi 3.1415926
int main( )
{
float fR1 = 1.2,fR1 = 2.3;
float Area ( float); // 函数原型声明
cout << "The area is,"<< Area(fR1) << endl; // 函数调用 1
cout << "The area is,"<< Area(fR2) << endl; // 函数调用 2
}
float Area ( float fR)
{
return (Pi * fR * fR);
}
45
例 1.2.6
# include <iostream.h>
# define Pi 3.1415926
int main()
{
float flR = 1.2,fArea;
inline float Area ( float); // 内联函数以声明为主
fArea = Area(flR);
cout <<"The area is,"<< fArea << endl;
}
inline float Area ( float fR) // 定义内联函数
{
return (Pi * fR * fR);
}
46
内联函数定义方法
一种是将函数定义内嵌在类的接口中
一种是定义在类接口的外部
注意,由于编译器必须知道内联函数的函
数体才能进行内联替换,因此,内联函数
在程序中被调用之前,必须被编译器看见,
即内联函数必须在调用之前定义或声明
47
传值调用与引用类型
传值调用(即, 值传递, )是 C++函数调
用的重要特征,即调用函数向被调用函数
传送的是参数值
引用( reference)。这一概念的引入,大大
简化了许多语法规则,并使得一些本来困
难或不可能的实体操作成为可能
48
例 1.2.7
#include <iostream.h>
int main( )
{
int x = 3,y = 5;
cout<<"Befor \'swap\':x ="<<x<<",y ="<<y<<endl;
void swap(int,int);
swap(x,y);
cout<<"After \'swap\':x ="<<x<<",y ="<<y<<endl;
}
void swap(int a,int b)
{
int temp;
temp = a; a = b; b = temp;
cout<<"In \'swap\':a ="<<a<<",b ="<<b<<endl;
}
49
例 1.2.8
# include <iostream.h>
int main()
{
int i = 5;
int & ri1 = i;
cout << "i=" << i << ",ri1=" << ri1 << endl;
i* = 3; // 改写变量
cout << "i=" << i << ",ri1=" << ri1 << endl;
ri1 += 5; // 改写引用
cout << "i=" << i << ",ri1=" << ri1 << endl;
}
50
例 1.2.9
# include <iostream.h>
int main()
{
int i = 5;
int & ril = i;
cout << "&i=" << &i << ",&ril = " << &ril << endl;
// &为求地址运算符
}
51
引用参数的 swap()函数
# include <iostream.h>
int main()
{
int x = 3,y = 5;
void swap(int &,int &); // 引用参数
swap(x,y);
cout<<"x = "<< x << ",y = "<< y << endl;
}
void swap(int & n1,int & n2)
{
int temp = n1;
n1 = n2;
n2 = temp;
}
52
库函数应用
库函数是 C++厂商收集的一些成熟的函数,
以供用户, 拿来就用, 。程序员使用库函
数无须再自行定义,只要注意事先了解以
下 3点便可,
· 函数的功能;
· 函数的原型 —— 函数名、参数个数及类
型、返回类型,以便正确调用;
· 使用库函数所需的头文件 —— 其中有函
数原型声明。程序员使用库函数之前只需
在程序中使用 # include指令嵌入相应的头
文件而不必再进行函数的原型说明
53
例 1.2.12
#include <iostream.h>
#include <math.h> // 嵌入数学函数库头
文件
int main()
{
float f;
cout<<"Enter a real number:";
cin>>f;
cout<<"The sqnare root of
“<<f<<”is:”<<sqrt(f)<<endl;
// sqrt是数学函数库 math中的一个库函
数
}
54
15个标准头文件
文件名 功 能 文件名 功 能
assert.h 程序断言诊断 signal.h 中断信号处理
ctype.h 字符处理 stdarg.h 可变参数的宏处理
errno.h 报告库函数出错 stddef.h 公共定义
float.h 实型类型的特征参数 stdio.h I/O函数库
limit.h 整型量大小的限制参数 stdlib.h 常用函数库
local.h 地方特征 string.h 字符串处理
math.h 数学函数库 time.h 日期与时间函数库
setjmp.h 非局部跳转
55
类与对象
一个简单的面向对象的例子
类的定义与实现
对象的生成与构造函数
对象的撤销与释放函数
友元
56
一个简单的面向对象的例子
一个面向对象的 C++程序由三部分组成,
· 类接口的定义;
· 主函数的编写;
· 类的实现 —— 成员函数的定义
57
面向对象的程序描述的圆
# include <iostream.h>
# define Pi 3.1415926
class Circle{ // 定义一个 Circle类,描述了抽象的圆
private,// 私有成员
float mfR; // 数据成员:半径
public,
Circle( float fR) ; // 成员函数:构造函数
void OutputArea(); // 成员函数:求面积
void OutputCircum(); // 成员函数:求周长
};
58
int main() // 进行具体的计算
{
Circle a(1.23),b(5.67); // 声明两个 Circle类对象 a和 b
a.OutputArea(); // 输出对象 a的面积
a.OutputCircum(); // 输出对象 a的周长
b.OutputArea(); // 输出对象 b的面积
b.OutputCircum(); // 输出对象 b的周长
}
Circle,,Circle (float fR) // 构造函数定义
{
mfR = fR;
}
void Circle::OutputArea() // 成员函数 OutputArea()的定义
{
cout<<"The area is,"<< Pi * mfR * mfR << endl;
}
void Circle::OutputCircum() // 成员函数 OutputCircum()的定义
{
cout<<"The circumference is,"<< 2.0 * Pi * mfR << endl;
}
59
类的定义与实现
类的定义包含两部分,
· 数据成员:描述某类对象的属性;
· 成员函数:描述某类对象的行为和变化等
私有成员不允许外界直接访问,只能由本类的成
员函数访问。外界与对象间的信息传送只能通过
公开成员进行,数据成员是对象隐藏的部分,由
关键词 private说明为私有的
由关键词 public说明为公开的,信息隐藏是面向对
象程序设计的基本原则,它将外界不需要知道的
信息都隐藏起来,以减少程序设计的复杂性。因
此默认的成员都是私有的,即当私有成员放在类
接口的开头部分时,关键词 private可以缺省
60
定义内联成员函数的方法
将成员函数直接定义在类的定义中
将成员函数定义在类定义之外时使用关键
字 inline
61
成员函数直接定义在类的定义中
# include <iostream.h>
# define Pi 3.1415926
class Circle{
private,
float mfR;
public,
void Circle::OutputArea() // 内联 OutputArea()
{
cout << "The area is,"<< Pi * mfR * mfR << endl;
}
void Circle::OutputCircum() // 内联 OutputCircum()
{
cout << "The circumference is," << 2.0 * Pi * mfR << endl;
}
};
62
成员函数定义在类定义之外时使用关键字 inline
# include <iostream.h>
# define Pi 3.1415926
class Circle{
private,
float mfR;
public,
void OutputArea();
void OutputCircum();
};
inline void Circle::OutputArea() // 内联的 OutputArea()定义
{
cout <<"The area is," << Pi * mfR * mfR << endl;
}
inline void Circle::OutputCircum() // 内联的 OutputCircum()定义
{
cout <<"The circumference is," << 2.0 * Pi * mfR << endl;
}
63
对象的生成与构造函数
创建对象时,要做的工作是,
· 给对象一个标识符;
· 给对象开辟一个内存空间;
· 将对象中的成员数据初始化
64
构造函数的特点
构造函数具有特定名字 ──与类名相同。如类
Circle的构造函数名也为 Circle 。
构造函数不能标以返回类型。它的返回值是隐含
的,是指向类本身的值。因此在例 1.3.1中定义的
构造函数没有返回类型。
构造函数也可以定义为内联函数
当系统执行对象声明语句时,构造函数会被自动
调用,去初始化被声明的对象删除
构造函数允许参数缺省调用
65
对象的撤销与释放函数
释放函数在对象撤销时被自动调用,用于
执行一些清理任务,如释放由构造函数分
配的内存等
释放函数有如下一些特点,
· 与类同名,之前冠以波浪号,以区别于
构造函数;
· 不指定返回类型;
· 不能指定参数。
66
友元
用 friend 声明了的外部函数称为这个类的友
元函数
元函数的使用有三个要点,
· 在类定义中用关键字 friend声明;
· 在类定义之外定义;
· 使用类对象引用作参数。
外部友元函数的作用域是所在类的类作用域
友元函数不仅可以访问对象的公开成员,而
且可以访问对象的私有成员
67
友元函数是另一个类的成员函数
友元函数作为一个类的成员函数时,除应
当在它所在的类定义中声明之外,还应当
在另一个类中声明它的友元关系
友元函数既可以引用本类对象的私有成员,
这时毋须本类对象的引用参数;还可以引
用声明它是友元的类对象中的私有成员,
这时必须有友员类对象的引用参数
一个类的成员函数作另一个类的友元函数
时,必须先定义它,而不仅仅是声明它
68
友元关系
class x {
private,成员 1
…… ……
public,
pf(); ……
}
class x {
private,成员 1
…… public,
pf();
friend f(); ……
}
f();
f();
可以访 问
可以访 问
不可访 问
声明友元关 系
可以访 问 可以访 问
69
例 1.3.2
#include <iostream.h>
#include <string.h>
class Girl {
char * name,* dial;
public,
Girl(char * n,char * d)
{
name=new char[strlen(n)+1];
strcpy(name,n);
dial=new char[strlen(d)+1];
strcpy(dial,d);
}
friend void disp( Girl& ); //声明友元函数
~Girl(){ delete name;delete dial;}
};
void disp(Girl &x) //定义外部友元函数,不是定义成员函数
{
cout<<"Girl\'s name is:"<<x.name;
<<",tel:"<<x.dial<<"\n";
}
main(void)
{
Girl e("Eluza","0351-7075461");
disp(e); //调用友元函数
}
70
C++程序开发过程与环境
C++程序开发的基本过程
C++的版本
71
C++程序开发的基本过程
计算机由硬件和软件两部分组成。硬件是
计算机的物理组成,包括一些电路板、电
子元件、接插件以及电源、外壳等。光有
硬件,计算机还不能工作。计算机的工作
是由程序控制的。程序是对计算机完成工
作的成员函数的描述
72
一个程序的开发需要经过如下步骤
1,分析问题,建立问题的模型
2,表现模型
3,程序的编译(或解释)与连接
4,程序的测试与调试
5,程序的维护
73
表现模型
表现模型就是用一种符号系统 —— 语言来
描述模型。或者说是用一种语言来写程序。
这种语言就称为程序设计语言
程序设计语言分为低级语言(面向机器的
语言)和高级语言两大类
高级程序设计语言可分为面向过程的程序
设计语言和面向对象的程序设计语言两大
类
74
程序测试的正确指导思想
以任何程序都存在错误为前提
测试的目的是找出程序中的错误,而不是
证明程序的正确
为了保证测试成功,需要很好地设计一组
测试用例,试运行程序
一般说来,测试不可能是完全的,成功的
测试是能够找出更多的错误的测试
75
维护程序的原因
原来的程序没有完全满足用户要求;
用户要求的改变;
程序中遗留有错误,在运行中被发现
76
程序开发的一般过程
提 出 问 题
分析问题建立模型
表 现 模 型
编辑源程序
编 译
连 接
测试与调试
运 行 维 护
错 误
目标文件
可执行文件
未发现错误
源程序文件
源程序代码
模型
问题
编
辑
错
误
建
模
错
误
分
析
错
误
不再适宜
77
C++的版本
C++是以 C语言为基础扩充、发展起来的一
种优秀的通用程序设计语言。它保持了 C
语言的紧凑、灵活、高效和移植性好的优
点,又吸收了一些著名程序设计语言的优
秀特性:从 Simula中吸收了类的机制;从
ALGOL 68中吸收了运算符重载、引用和在
局部的任何地方声明变量;综合了 Ada的
类属和异常处理机制
78
C++的发展历程
1960 1964 1968 1972 1976 1980 1984 1988 1992 1996 2000
ALGOL 60 ALGOL 68
CPL BCPL B C ANSI C 87ANSI C
Turbo C/C++,Borland C/C++
Borland C++ Bulder
Microsoft C/C++
Visual C++
Java Simula 67
C++ ANSI C++
C#
带类的 C
79
习题
第 1章 C++程序开发初步
2
第 1章 C++程序开发初步
最简单的 C++程序结构
函数
类与对象
C++程序开发过程与环境
3
程序设计中主要应用两大类模型
面向过程的模型
概括为,
数据结构 + 算法
面向对象的模型
认为世界是由一些对象( objects)组成的,
每一个对象包括属性和方法两部分;属性
是描述对象特征的一些数据或数据结构,
方法表明对象的变化或一个对象对其他对
象的作用,对象间通过消息传递进行通信
4
最简单的 C++程序结构
一个简单的 C++程序
运算符与表达式
数据类型
变量与常量
5
一个简单的 C++程序
# include <iostream.h>
int main ( )
{
int x,y,s;
// 定义 3个整数:两个代表加数,一个代表和
cout <<,输入两个整数:” ; // 给用户发出输入两个
数的提示
cin >> x >> y; // 输入两个整数到 x和 y
s = x + y; // 将 x和 y相加,送到 s中
cout <<,x + y =” // 输出提示
<< s // 输出 s的值
<< endl; // 换行,语句结束
return 0;
}
6
上例说明
C++的注释符有:, //”后面与, /*”和, */”之
间的
,;, 是 C++语句的结束符,表明一个语句
的结束
x”,,y”和, s”称为三个变量,是三个存储
数据的空间的名字
,cout”称为标准输出设备,通常指显示器
,cin”称为标准输入设备,通常指键盘
,endl”表示换行
,# include”称为文件包含
7
运算符与表达式
运算符是一种程序记号,它作用于操作数
而触发某种操作
由运算符和操作数组成的符号序列,就称
为表达式
8
最基本的运算符
算术运算符
赋值运算符
复合赋值运算符
9
运算符在表达式中的运算顺序
运算符的优先级别
运算符与操作数的结合方向
运算符的先后排列顺序
10
各种运算符间的优先级别和结合性
运算符 结合性 优先级别
单目减,- ← 高
低
双目算术
运算符,
* / →
+ - →
标准输入输出,>> << →
赋值,= ←
11
例 1.1.1
#include <iostream.h>
int main()
{
int x,y;
cout << "x = 3,y = 8,x *= y + 1:" << ( x = 3,y = 8,x *= y + 1 )<< endl;
cout << "x = 3,y = 8,x = x * y + 1:" << ( x = 3,y = 8,x = x * y + 1) <<
endl;
return 0;
}
12
++与 - -有两种使用形式
前缀形式,即它们在操作数前,如 ++x,- -x
后缀形式,即它们在操作数后,如 x++,x- -
++表达式与 - -表达式独立使用时,前缀形式
与后缀形式无区别,但它们在表达式中被
引用时,结果是不同的。
前缀形式是先增(减) 1,后被引用;后缀
形式是先被引用,后增(减) 1
13
例 1.1.2
# include <iostream.h>
int main( )
{
int x,y;
x = 5,y = x++; // 先引用后增 1
cout << "x=5,y=x++:" << y << ",x=" << x << endl;
x = 5,y = ++x ; // 先增 1后引用
cout << "x=5,y=++x:" << y << ",x=" << x << endl;
return 0;
}
14
数据类型
整型类型与实型类型
字符类型
字符串
算术数据的类型转换
sizeof 运算符
15
数据的规范化
为数据分配相应大小的存储空间;
确定数据值的范围;
确定数据的表示精度;
确定数据可以进行的运算种类。
16
最常用的数据类型的比较
数据类型
关键字
意义 存储
空间
表数精度
(有效数字 )
表数范围 运算类型
char 字符 8位 +,-,%
short 短整数 16位 -32768~32767 +,-,*
,/、
%
int 整数 32位 -2 147 483 648~2 147 483 647
float 单精度浮点 32位 7位 ?( 3.4× 10-38~3.4× 1038) +,-,*
,/、
% double 双精度浮点 64位 16位 ?( 2.23× 10-308~1.79× 10308)
long
doubl
e
长双精度 80位 18位 ± ( 3.37× 10-4932~1.18× 104932
)
17
整型类型与实型类型
整型就是不带有小数点的数据类型
C++还把整型数分为带符号和不带符号两
大类
实数一般用小数形式或科学记数法(指数
形式)书写
18
C++的转义字符序列
序 列 值 字符 功 能
\a 0X07 BEL 警告响铃
\b 0X08 BS 退格
\f 0X0C FF 走纸
\n 0X0A LF 换行
\r 0X0D CR 回车
\t 0X09 HT 水平制表
\v 0X0B VT 垂直制表
\\ 0X5c \ 反斜杠
\' 0X27 ' 单引号
\" 0X22 " 双引号
\? 0X3F? 问号
\o 整数 任意 0[L1]:最多为 3位的八进制数字串
\xH 整数 任意 H:十六进制数字串
19
字符串
字符串常量也称字符串文字或字符串,它
们是括在一对双撇号内的字符序列
字符串常量与字符型常量在内部存储上是
不同的
20
算术数据的类型转换
在表达式中,常常会发生数据类型的转换,
即将数据由一种类型转换成另一种类型
下面介绍这些类型转换规则。
常规转换
传送转换
用类型运算符进行显式转换
21
例 1.1.4
#include <iostream.h>
int main( )
{
short int a = -32768,b,i = 1234567890; //i溢出
unsigned short int ua = 32768,ub;
cout << "b=ua:" << (b=ua) << endl; //注意 ua对 int溢出
cout << "ub=a:" << (ub=a) << endl; //注意有符号负数向无符号数转换
cout << i;
}
22
sizeof 运算符
sizeof是一个单目运算符,用以计算操作数
在内存中占用的字节数。
它的操作数可以是以下两种情况,
括在圆括号中的类型标识符
一个表达式
sizeof 运算符具有最高优先级,最高优先
级中的运算符都是从右向左结合的
23
例 1.1.5
#include <iostream.h>
int main( ) // 该程序在 16位和 32位系统中的运行结果不同!
{
cout << "size of unsigned char:" << sizeof(unsigned char) << endl;
cout << "size of char:" << sizeof(char) << endl;
cout << "size of unsigned int:" << sizeof(unsigned int) << endl;
cout << "size of short int:" << sizeof(short int) << endl;
cout << "size of int:" << sizeof(int) << endl;
cout << "size of unsigned long:" << sizeof(unsigned long) << endl;
cout << "size of long:" << sizeof(long) << endl;
cout << "size of float:" << sizeof(float) << endl;
cout << "size of double:" << sizeof(double) << endl;
cout << "size of long double:" << sizeof(long double) << endl;
}
24
变量与常量
程序变量
字面常量与符号常量
25
程序变量
程序变量简称变量。变量有以下特点,
变量指称了程序中使用的一个被命名存储区域
(称程序实体),以存放可由程序修改的值,变
量在某一时刻的值称为变量值。
变量的名称为变量名。 C++规定变量名由如下三
种符号组成,
大小写字母 —— 可用于变量名的任何位置;
下划线 —— 可用于变量名的任何位置;
数字 —— 不能用于变量名的首部。
每个变量应属于一个特定的类型
26
例 1.1.6
# include <iostream.h>
int main( )
{
int i; // 声明 i为整型
i = 3; // 给变量 i赋值 3
cout << "The first\"i\" is," << i<< endl;
i = 5; // 给变量 i再赋值 5
cout << "The second \"i\" is," << i << endl;
cout << "Enter a number,";
cin >> i; // 由键盘给变量 i输入一个值
cout << "\nThe last \"i\" is," << i << endl;
}
27
字面常量与符号常量
常量可以是字面常量(也称直接常量)或
符号常量。前面使用的基本上都是字面常
量
下面介绍两种符号常量,
( 1)用 const定义的符号常量
( 2)用宏定义模拟符号常量
28
例 1.1.7
/*****************************
* 程序名,area_circum *
* 功 能:计算圆的面积与周长 *
******************************/
#include <iostream.h>
int main( )
{
float fArea,fCircum;
fArea = 3.1415926 * 2.0 * 2.0;
cout << "The area is:" << fArea << endl;
fCircum = 3.1415926 * 2.0 * 2.0;
cout << "The circum is:" << fCircum << endl;
}
29
用宏定义模拟符号常量
# include <iostream.h>
# define Pi 3.1415926 // 定义宏
# define r 2.0 // 定义宏
int main()
{
float fArea,fCircum;
fArea = Pi * r * r; // 引用宏
cout << "The area is," << fArea << endl;
fCircum = 2.0 * Pi * r; // 引用宏
cout << "The circumference is," << fCircum << endl;
}
30
函数
函数的意义与用法
函数定义与函数结构
函数原型与函数声明
函数调用与内联函数
传值调用与引用类型
库函数应用
31
函数的意义与用法
函数是 C++程序中组织过程的机制。它对
较大的程序比较有效。这里,主要介绍函
数的用法,因此仍然使用前面介绍过的求
圆的面积的例子,只不过用函数的形式来
描述
32
例 1.2.1
# include <iostream.h>
# define Pi 3.1415926
int main( )
{
float flR = 1.2,fArea;
float Area (float); // 函数声明
fArea = Area(flR); // 函数调用
cout <<"The area is," << fArea << endl;
}
float Area ( float fR) // 定义求圆面积的函数
{
return (Pi * fR * fR);
}
33
C++程序的一般结构
系统调用
返回系统
f1() f11()
{ ④ {
↓③ ↓⑤
main() ② f11(); ⑥ }
{ ↓⑦
↓① } f21()
f1(); ⑧ {
↓⑨ f2() 12 ↓13
f2(); 10 { }
↓21 ↓11 14
} f21(); f22()
20 ↓15 16 {
f22(); ↓17
↓19 18 }
}
34
函数定义与函数结构
一个 C++函数的定义由函数头与函数体两
部分组成,形式如下,
函数首部
{
函数体
}
35
函数首部
函数首部是函数的接口部分,其组成形式
如下,
类型名 函数名 ( 形式参数表列 )
函数类型规定为函数返回值的类型
函数名是函数的标识,它应是一个有效的
C++标识符
形式参数表列是括在园括号中的 0个或多
个以逗号分隔的形式参数
36
函数体
一个函数体是一个语句块,是用一对花括
号封装的语句序列。它描述了函数实现一
个功能的过程。它最后执行一个函数返回,
返回的作用是,
将流程从当前函数返回其上级(调用函
数);
撤销函数调用时为各参数及变量分配的内
存空间;
向调用函数返回顶多一个值
37
例 1.2.2
void Area ( float fR) // 定义求圆面积的函数
{
cout << "The area is,"<< (Pi * fR * fR) << endl;
return;
}
或
void Area ( float fR) // 定义求圆面积的函数
{
cout << "The area is,"<< (Pi * fR * fR) << endl;
return;
}
38
主函数 main()
main()函数是一个特殊的函数。它的名字
是固定的。它可看作是由操作系统调用的
一个函数。其返回值可以是 void型或 int型
(可以缺省)。当其返回值为 int型时,用 0
或非 0,告诉操作系统程序是否正常结束
39
例 1.2.3
# include <iostream.h>
main()
{
cout << "ok!";
return (0);
}
40
函数原型
函数原型也称函数模型,是由函数定义中
抽取出来的能代表函数应用特征的部分,
· 函数类型
· 函数名
· 参数个数及其类型
函数原型的形式为,
类型 函数名(参数类型1,参数类型
2,…,参数类型 n)
41
函数提前声明
当函数定义在前调用在后时,编译器在调
用函数之前,能从其定义中抽取函数原型
当函数调用在前定义在后时,要求程序员
在调用之前用函数原型对函数进行声明,
以便编译器从中得到函数原型所提供的有
关信息
函数声明中的参数名对编译器没有意义
42
函数调用与内联函数
函数调用的作用是,
· 用实参数(如例 1.2.1中的 nR)向形式参数
(如例 1.2.1中的 fR)传递数据;
· 中断现行(调用)函数,把流程转向(被
调用)函数的入口处,开始执行被调函数
在调用与返回过程中,需要付出一定的时间
与空间代价用于处理现场。当函数较小,又
反复使用时,处理现场的开销比重会急剧增
大。若把函数体嵌入函数调用处,便可以大
大提高运行速度,节省开销。内联函数就可
以自动实现这一功能
43
例 1.2.4
# include <iostream.h>
# define Pi 3.1415926
int main( )
{
float fR1 = 1.2,fR1 = 2.3,fArea;
float Area ( float); // 函数原型
声明
fArea = Area(fR1); // 函数调用 1
cout <<"The area is,"<< fArea << endl;
fArea = Area(fR2); // 函数调用 2
cout <<"The area is,"<< fArea << endl;
}
float Area ( float fR)
{
return (Pi * fR * fR);
}
44
例 1.2.5
# include <iostream.h>
# define Pi 3.1415926
int main( )
{
float fR1 = 1.2,fR1 = 2.3;
float Area ( float); // 函数原型声明
cout << "The area is,"<< Area(fR1) << endl; // 函数调用 1
cout << "The area is,"<< Area(fR2) << endl; // 函数调用 2
}
float Area ( float fR)
{
return (Pi * fR * fR);
}
45
例 1.2.6
# include <iostream.h>
# define Pi 3.1415926
int main()
{
float flR = 1.2,fArea;
inline float Area ( float); // 内联函数以声明为主
fArea = Area(flR);
cout <<"The area is,"<< fArea << endl;
}
inline float Area ( float fR) // 定义内联函数
{
return (Pi * fR * fR);
}
46
内联函数定义方法
一种是将函数定义内嵌在类的接口中
一种是定义在类接口的外部
注意,由于编译器必须知道内联函数的函
数体才能进行内联替换,因此,内联函数
在程序中被调用之前,必须被编译器看见,
即内联函数必须在调用之前定义或声明
47
传值调用与引用类型
传值调用(即, 值传递, )是 C++函数调
用的重要特征,即调用函数向被调用函数
传送的是参数值
引用( reference)。这一概念的引入,大大
简化了许多语法规则,并使得一些本来困
难或不可能的实体操作成为可能
48
例 1.2.7
#include <iostream.h>
int main( )
{
int x = 3,y = 5;
cout<<"Befor \'swap\':x ="<<x<<",y ="<<y<<endl;
void swap(int,int);
swap(x,y);
cout<<"After \'swap\':x ="<<x<<",y ="<<y<<endl;
}
void swap(int a,int b)
{
int temp;
temp = a; a = b; b = temp;
cout<<"In \'swap\':a ="<<a<<",b ="<<b<<endl;
}
49
例 1.2.8
# include <iostream.h>
int main()
{
int i = 5;
int & ri1 = i;
cout << "i=" << i << ",ri1=" << ri1 << endl;
i* = 3; // 改写变量
cout << "i=" << i << ",ri1=" << ri1 << endl;
ri1 += 5; // 改写引用
cout << "i=" << i << ",ri1=" << ri1 << endl;
}
50
例 1.2.9
# include <iostream.h>
int main()
{
int i = 5;
int & ril = i;
cout << "&i=" << &i << ",&ril = " << &ril << endl;
// &为求地址运算符
}
51
引用参数的 swap()函数
# include <iostream.h>
int main()
{
int x = 3,y = 5;
void swap(int &,int &); // 引用参数
swap(x,y);
cout<<"x = "<< x << ",y = "<< y << endl;
}
void swap(int & n1,int & n2)
{
int temp = n1;
n1 = n2;
n2 = temp;
}
52
库函数应用
库函数是 C++厂商收集的一些成熟的函数,
以供用户, 拿来就用, 。程序员使用库函
数无须再自行定义,只要注意事先了解以
下 3点便可,
· 函数的功能;
· 函数的原型 —— 函数名、参数个数及类
型、返回类型,以便正确调用;
· 使用库函数所需的头文件 —— 其中有函
数原型声明。程序员使用库函数之前只需
在程序中使用 # include指令嵌入相应的头
文件而不必再进行函数的原型说明
53
例 1.2.12
#include <iostream.h>
#include <math.h> // 嵌入数学函数库头
文件
int main()
{
float f;
cout<<"Enter a real number:";
cin>>f;
cout<<"The sqnare root of
“<<f<<”is:”<<sqrt(f)<<endl;
// sqrt是数学函数库 math中的一个库函
数
}
54
15个标准头文件
文件名 功 能 文件名 功 能
assert.h 程序断言诊断 signal.h 中断信号处理
ctype.h 字符处理 stdarg.h 可变参数的宏处理
errno.h 报告库函数出错 stddef.h 公共定义
float.h 实型类型的特征参数 stdio.h I/O函数库
limit.h 整型量大小的限制参数 stdlib.h 常用函数库
local.h 地方特征 string.h 字符串处理
math.h 数学函数库 time.h 日期与时间函数库
setjmp.h 非局部跳转
55
类与对象
一个简单的面向对象的例子
类的定义与实现
对象的生成与构造函数
对象的撤销与释放函数
友元
56
一个简单的面向对象的例子
一个面向对象的 C++程序由三部分组成,
· 类接口的定义;
· 主函数的编写;
· 类的实现 —— 成员函数的定义
57
面向对象的程序描述的圆
# include <iostream.h>
# define Pi 3.1415926
class Circle{ // 定义一个 Circle类,描述了抽象的圆
private,// 私有成员
float mfR; // 数据成员:半径
public,
Circle( float fR) ; // 成员函数:构造函数
void OutputArea(); // 成员函数:求面积
void OutputCircum(); // 成员函数:求周长
};
58
int main() // 进行具体的计算
{
Circle a(1.23),b(5.67); // 声明两个 Circle类对象 a和 b
a.OutputArea(); // 输出对象 a的面积
a.OutputCircum(); // 输出对象 a的周长
b.OutputArea(); // 输出对象 b的面积
b.OutputCircum(); // 输出对象 b的周长
}
Circle,,Circle (float fR) // 构造函数定义
{
mfR = fR;
}
void Circle::OutputArea() // 成员函数 OutputArea()的定义
{
cout<<"The area is,"<< Pi * mfR * mfR << endl;
}
void Circle::OutputCircum() // 成员函数 OutputCircum()的定义
{
cout<<"The circumference is,"<< 2.0 * Pi * mfR << endl;
}
59
类的定义与实现
类的定义包含两部分,
· 数据成员:描述某类对象的属性;
· 成员函数:描述某类对象的行为和变化等
私有成员不允许外界直接访问,只能由本类的成
员函数访问。外界与对象间的信息传送只能通过
公开成员进行,数据成员是对象隐藏的部分,由
关键词 private说明为私有的
由关键词 public说明为公开的,信息隐藏是面向对
象程序设计的基本原则,它将外界不需要知道的
信息都隐藏起来,以减少程序设计的复杂性。因
此默认的成员都是私有的,即当私有成员放在类
接口的开头部分时,关键词 private可以缺省
60
定义内联成员函数的方法
将成员函数直接定义在类的定义中
将成员函数定义在类定义之外时使用关键
字 inline
61
成员函数直接定义在类的定义中
# include <iostream.h>
# define Pi 3.1415926
class Circle{
private,
float mfR;
public,
void Circle::OutputArea() // 内联 OutputArea()
{
cout << "The area is,"<< Pi * mfR * mfR << endl;
}
void Circle::OutputCircum() // 内联 OutputCircum()
{
cout << "The circumference is," << 2.0 * Pi * mfR << endl;
}
};
62
成员函数定义在类定义之外时使用关键字 inline
# include <iostream.h>
# define Pi 3.1415926
class Circle{
private,
float mfR;
public,
void OutputArea();
void OutputCircum();
};
inline void Circle::OutputArea() // 内联的 OutputArea()定义
{
cout <<"The area is," << Pi * mfR * mfR << endl;
}
inline void Circle::OutputCircum() // 内联的 OutputCircum()定义
{
cout <<"The circumference is," << 2.0 * Pi * mfR << endl;
}
63
对象的生成与构造函数
创建对象时,要做的工作是,
· 给对象一个标识符;
· 给对象开辟一个内存空间;
· 将对象中的成员数据初始化
64
构造函数的特点
构造函数具有特定名字 ──与类名相同。如类
Circle的构造函数名也为 Circle 。
构造函数不能标以返回类型。它的返回值是隐含
的,是指向类本身的值。因此在例 1.3.1中定义的
构造函数没有返回类型。
构造函数也可以定义为内联函数
当系统执行对象声明语句时,构造函数会被自动
调用,去初始化被声明的对象删除
构造函数允许参数缺省调用
65
对象的撤销与释放函数
释放函数在对象撤销时被自动调用,用于
执行一些清理任务,如释放由构造函数分
配的内存等
释放函数有如下一些特点,
· 与类同名,之前冠以波浪号,以区别于
构造函数;
· 不指定返回类型;
· 不能指定参数。
66
友元
用 friend 声明了的外部函数称为这个类的友
元函数
元函数的使用有三个要点,
· 在类定义中用关键字 friend声明;
· 在类定义之外定义;
· 使用类对象引用作参数。
外部友元函数的作用域是所在类的类作用域
友元函数不仅可以访问对象的公开成员,而
且可以访问对象的私有成员
67
友元函数是另一个类的成员函数
友元函数作为一个类的成员函数时,除应
当在它所在的类定义中声明之外,还应当
在另一个类中声明它的友元关系
友元函数既可以引用本类对象的私有成员,
这时毋须本类对象的引用参数;还可以引
用声明它是友元的类对象中的私有成员,
这时必须有友员类对象的引用参数
一个类的成员函数作另一个类的友元函数
时,必须先定义它,而不仅仅是声明它
68
友元关系
class x {
private,成员 1
…… ……
public,
pf(); ……
}
class x {
private,成员 1
…… public,
pf();
friend f(); ……
}
f();
f();
可以访 问
可以访 问
不可访 问
声明友元关 系
可以访 问 可以访 问
69
例 1.3.2
#include <iostream.h>
#include <string.h>
class Girl {
char * name,* dial;
public,
Girl(char * n,char * d)
{
name=new char[strlen(n)+1];
strcpy(name,n);
dial=new char[strlen(d)+1];
strcpy(dial,d);
}
friend void disp( Girl& ); //声明友元函数
~Girl(){ delete name;delete dial;}
};
void disp(Girl &x) //定义外部友元函数,不是定义成员函数
{
cout<<"Girl\'s name is:"<<x.name;
<<",tel:"<<x.dial<<"\n";
}
main(void)
{
Girl e("Eluza","0351-7075461");
disp(e); //调用友元函数
}
70
C++程序开发过程与环境
C++程序开发的基本过程
C++的版本
71
C++程序开发的基本过程
计算机由硬件和软件两部分组成。硬件是
计算机的物理组成,包括一些电路板、电
子元件、接插件以及电源、外壳等。光有
硬件,计算机还不能工作。计算机的工作
是由程序控制的。程序是对计算机完成工
作的成员函数的描述
72
一个程序的开发需要经过如下步骤
1,分析问题,建立问题的模型
2,表现模型
3,程序的编译(或解释)与连接
4,程序的测试与调试
5,程序的维护
73
表现模型
表现模型就是用一种符号系统 —— 语言来
描述模型。或者说是用一种语言来写程序。
这种语言就称为程序设计语言
程序设计语言分为低级语言(面向机器的
语言)和高级语言两大类
高级程序设计语言可分为面向过程的程序
设计语言和面向对象的程序设计语言两大
类
74
程序测试的正确指导思想
以任何程序都存在错误为前提
测试的目的是找出程序中的错误,而不是
证明程序的正确
为了保证测试成功,需要很好地设计一组
测试用例,试运行程序
一般说来,测试不可能是完全的,成功的
测试是能够找出更多的错误的测试
75
维护程序的原因
原来的程序没有完全满足用户要求;
用户要求的改变;
程序中遗留有错误,在运行中被发现
76
程序开发的一般过程
提 出 问 题
分析问题建立模型
表 现 模 型
编辑源程序
编 译
连 接
测试与调试
运 行 维 护
错 误
目标文件
可执行文件
未发现错误
源程序文件
源程序代码
模型
问题
编
辑
错
误
建
模
错
误
分
析
错
误
不再适宜
77
C++的版本
C++是以 C语言为基础扩充、发展起来的一
种优秀的通用程序设计语言。它保持了 C
语言的紧凑、灵活、高效和移植性好的优
点,又吸收了一些著名程序设计语言的优
秀特性:从 Simula中吸收了类的机制;从
ALGOL 68中吸收了运算符重载、引用和在
局部的任何地方声明变量;综合了 Ada的
类属和异常处理机制
78
C++的发展历程
1960 1964 1968 1972 1976 1980 1984 1988 1992 1996 2000
ALGOL 60 ALGOL 68
CPL BCPL B C ANSI C 87ANSI C
Turbo C/C++,Borland C/C++
Borland C++ Bulder
Microsoft C/C++
Visual C++
Java Simula 67
C++ ANSI C++
C#
带类的 C
79
习题