Upload
kokjj87
View
109
Download
2
Embed Size (px)
Citation preview
1Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 1
2 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ Programming in UNIX
课程介绍C++ 语法基础 面向对象程序设计的概念 大量的编程实践
目标 熟练掌握 C++ 语法 具有面向对象程序设计的概念与能力 能熟练阅读复杂的 C++ 程序源代码 能独立的设计与完成面向对象的 C++ 程序
3 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
课程内容简介 1
C++ 语言基础保留字变量,常量表达式语句函数程序的结构数据结构与算法
数组、指针、引用、结构、链表与栈
4 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
课程内容简介 2
C++ 面向对象编程 类 构造函数与析构函数 静态成员与友员 函数重载 继承与多态
I/O 流模板异常
5 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序设计语言介绍 1
What computer understand?
bits
Assembler Language
Limited structure
Global scope
Machine code
Primitive High-Level Language
Function decomposition
Data separation
High level structure
6 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序设计语言介绍 2
Block Structured Language
Encapsulation
Flexible data scoping
Modularization
Object-Oriented Language
Inheritance
Polymorphism
Abstract data types
7 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 程序设计语言
1972 , AT&T, Bell Lab. Dennis Ritche, C language
1980, Bell Lab. Bjarne Stroustrup, C extension,
1983, C++ named
1997, ANSI (American National Standards Institute) C++
(standard C++)
8 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
What C++ will we learn in this course ?
Standard C++: ANSI C++ is more scalable to different
platform such as Unix, Microsoft
windows, Mac…
The standard C++ library got supported by most of industry providers.
You’d better don’t know C. ........???
We will try to avoid C library and C syntax.
A C++ file can be with .cc, .cp, .cpp extensions.
9 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
为什么选标准 C++
ANSI 规范了 C++ 的标准, 使之具有高度的可移植性。
C++ 程序能够运行得很快,可直接操作系统资源,保持机器层次的实现细节。
C++ 不要求图形环境, 对系统要求相对较低。
易于解决与旧工程的接口以及在数据库,存储和性能方面的技术限制。
C++ 是一种面向对象的多范型语言,可以将面向对象的模型映射成为C++ 的结构。它为开发者设计和编写一个解决方案提供了一定的选择范围。
10 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 的优点
Supports data abstraction and object-oriented programming
Contains all existing features of C, making the migration from C to C++ relatively easy
Is as portable and efficient as C
Can be linked to existing C libraries and functions
Provides strong static-type checking
Is a general-purpose language
11 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序员应该具备的计算机知识 1
操作系统与应用程序运行环境与运行机制
系统与命令 运行环境与命令行参数 进程 栈 堆
12 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Binary and Hexadecimal
Binary: 0101 1000
Decimal: 88
Hexadecimal: 0x58
1 byte = 8 bits.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
13 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序员应该具备的计算机知识 2
编辑器编译器
编译器的功能 解释执行与编译执行的差别 熟悉自己常用的编译器,查错能力
连接器库与库函数系统调用
14 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
软件开发周期
源程序编辑
编译
连接
调试
运行
15 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Software Lifecycle
开发测试维护更新
16 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
熟悉你的环境
可用的 UNIX 服务器1. www.openlab.com.cn
2. 192.168.0.21
3. 192.168.0.23
4. 192.168.0.26
Telnet 命令介绍 : telnet 192.168.0.21
Login: use your registered user account.
Password: type in your pass word.
17 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
创建自己的学习帐号
telnet www.openlab.com.cnlogin: tarena
Password: tarena
欢迎使用达内科技 ( 中国 ) 公司开放实验室的服务 !Welcome to the OpenLab of Tarena Technologies Inc. Cananda.
请按照以下提示创建您的用户帐号 .Please follow the steps to create your own account.
( 请输入您要注册的帐号 )Please enter your new account name:XXXXXXXX
( 请输入您的 E-Mail 地址 )Please enter your email address: [email protected]
18 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
用自己的帐号登录 UNIX 服务器
Escape character is '^]'.
SunOS 5.8
login: XXXXXXX
Choose a new password.
New password: *******
19 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序员经常用到的 UNIX 命令 1
简单的文件维护与管理ls, cd, mkdir, rm, cp, mv, cat, more
源程序的编写vi, ed
编译与连接gcc, g++, ld
运行与调试adb,gdb
20 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序员经常用到的 UNIX 命令 2
查看运行状态% ps –ef
% grep aaa a.txt (aaa is the chars in the file name a.txt)
% prstat (ctrl D to exit)
% kill pid (pid is a process id)
21 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
第一个 UNIX 上的 C++ 程序
用 vi 编辑器来编写 hello.cc 源程序% vi hello.cc
/*the first C++ program*/#include <iostream>using namespace std;//main functionint main(){
cout << "Hello world!" << endl;cout << "This is my first C++ program.\n";
}
22 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
g ++的常用参数
- c 编译成目标文件 .o
- o 指定输出文件名,输出文件名跟在 -o后面,用空格分隔。如果不使用这个选项,缺省的输出文件名为 a.out 。- g产生有调试信息的可执行文件- w 不产生警告信息- l 连接指定的库文件- L 指定库文件的路径- i 要包含的头文件- I 头文件的路径- E 显示预处理后的程序文件到屏幕上,可以用 -o 指定输出到文件- S 产生汇编程序如果没有 c 、 E 、 S就会生成可执行文件
23 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
编译 hello.cc
% g++ -c hello.cc
% ls
24 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
连接 hello.o
% g++ -o hello hello.o
% ls
% g++ hello.o
% ls
25 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
运行 hello 程序
% hello
% a.out
26 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 程序的基本结构 1
/*the first C++ program*/#include <iostream>using namespace std;
//main functionint main(){
cout << "Hello world!" << endl;cout << "This is my first C++ program.\n";
}
27 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 程序的基本结构 2
#include< > 与 #include" "
Name space: 提供了一个全局标识符和全局变量所在的作用域。int main()
注释函数函数的调用cout 语句
28 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
头文件
#include 语句#include < > 与 #include " "
使用#include <iostream>using namespace std;
少用#include <iostream.h>
29 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Main 函数
main 函数的作用Standard C++ main( )格式 :
int main( )
{
…
return 0; //the default return value is 0;
}
30 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
注释
C++ 的注释
31 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
基本的输出语句
cout
32 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 hi.cc
#include <iostream>
using namespace std;
int main( )
{
cout << "Hi Jian!" << endl;
cout << "Have a nice day." << endl;
return 0;
}
33 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 myself.cc
编写一个程序,打印出自己的:姓名 性别年龄家庭住址 电话号码爱好
每一条信息输出为一行
34 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
在 hi.cc 中使用字符串
#include <iostream>
using namespace std;
int main()
{
char name[ ] = "John";
cout << "Hi " << name << "!" << endl;
cout << "Have a nice day." << endl;
return 0;
}
35 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
字符与字符串类型
字符,字符串 /字符数组char ch = ‘A’;
char str1[20] = "Hello world!";
char str2[ ] = "Have a nice day!";
36 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
不同的 main() 格式
命令行参数% ls –l (or ls -al )
% vi hello.cc
在程序中使用命令行参数int main(int argc, char *argv[ ])
37 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
命令行参数程序 cmdline.cc
#include <iostream>
using namespace std;
int main (int argc, char* argv[ ])
{
for(int i=0; i<argc; i++)
{
cout << "argv[" << i << "]=" << argv[i] << endl;
}
}
38 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用命令行参数的 hi.cc
使用命令行参数,重新编写练习程序 cmdline.cc
% hi John
% hi Lisa
% hi "G. Bush"
39 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
基本输入语句
cin 语句
使用 cin 语句的 hi.cc 重写 hi.cc 程序,不带命令行参数 程序自动提示用户输入字符串来获得姓名与年龄
40 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 age.cc
#include <iostream>using namespace std;
int main(){ unsigned int age; char name [50]; cout << "please enter your name:" << endl; cin >> name; cout << "please enter your age:" << endl; cin >> age; cout << "your name is:" << name << endl; cout << "You were " << age -2 << " years old two years ago. \n";}
41 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
条件语句
if 语句if…else 语句不同 if 的等价与不等价形式
… char ch;
cin >> ch;
if (ch == ‘y’) //note the difference: if ( ch = ‘y’)
cout << "good" << endl;
else
cout << "try again." << endl;
…
42 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 grade.cc
This is your assignment.
43 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
44Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 2
45 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
字符集
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0 1 2 3 4 5 6 7 8 9
_
+ - * / % =
. , : ? ’ \ " ~ | ! # &
( ) [ ] { } ^ < >
空白
46 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 的保留字
auto, bool, break, case, catch, char, class, const, const_cast , continue, default, delete, do, double, else, enum, extern, false, float, for, friend, goto, if, inline, int, long, new, operator, private, protected, public, return, short, signed, sizeof, static, struct, switch, template, this, throw, true, try, typedef, union, unsigned, virtual, void, while, …
47 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
常量与变量
内存程序的内存使用
常量 变量动态内存
变量的类型
48 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 变量名
变量名( identifier)
第一个字符必须是字母或下划线只能使用字母,数字,或下划线中间不能有空格不能是保留字,不能与全局函数和数据类型同名
C++严格区分大小写( UNIX 中……)使用易懂的变量名(一般是相关的英语单词或者缩写)长度一般不要超过 32 个字符
不单是变量名,所有需要自己起名的地方都需要遵守这样的规则。
49 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 变量
C++ 是强类型语言每一个变量都有确定的类型,且保持不变
基本数据类型整型, int,
字符型 , char, 实型 , float, double,逻辑型 , bool ( standard c++ new feature ! )
50 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
基本数据类型 1
char, unsigned char, signed char,
int, unsigned int, signed int, short int, unsigned short int, signed short int, long int, signed long int, unsigned long int,
float, double, long double,
bool
void
: enum , struct , union , array , pointer , class
51 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
基本数据类型 2
实型数据 (float, double…) 无 unsigned.
52 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
The standard C++ new features
bool: 其值必为关键字 true 或 false
四个转型运算子: static_cast: compiling time to check data type(primitive).
const_cast: only for constant data type converting.
dynamic_cast: usually for top-down data type cast.
reinterpret_cast: more general cast for all data types.
(到多态的时候再详细讲)
53 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
变量与数据类型
C++ 是强类型语言先声明,后使用
C++ 编译器对变量声明的处理
54 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
一个使用变量的程序例子
#include <iostream>
using namespace std;
int main( )
{
int i;
i = 5;
cout << "i = " << i << endl;
i = 8;
cout << "i = " << i << endl;
return 0;
}
55 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
另一个使用变量的例子程序
#include <iostream>
using namespace std;
int main( )
{
i = 5; //see what happens…
cout << "i = " << i << endl;
i = 8;
cout << "i = " << i << endl;
return 0;
int i;
}
56 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
变量与变量的 size
变量都有类型变量在内存中的大小
int i;
double d;
cout << "size of i is " << sizeof( i ) << endl;
cout << "size of int is " << sizeof( int ) << endl;
cout << "size of d is " << sizeof( d ) << endl;
cout << "size of double is " << sizeof( double ) << endl;
57 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 size.cc
编写一个程序,打印出所有 C++ 基本类型的大小
#include <iostream>
using namespace std;
int main()
{
cout << "size of char is: " << sizeof(char) << endl;
cout << "size of unsigned char is: " << sizeof(unsigned char) << endl;
cout << "size of signed char is: " << sizeof(signed char) << endl;
cout << "size of int is: " << sizeof(int) << endl;
cout << "size of unsigned int is: " << sizeof(unsigned int) << endl;
cout << "size of signed int is: " << sizeof(signed int) << endl;
cout << "size of short int is: " << sizeof(short int) << endl;
……
}
58 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
变量的取值范围
变量的类型与值的范围常用类型的取值范围
59 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
常量
常量与常量的数据类型const double pi=3.14
60 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
const 限定符
限定一个常量或者函数方便编译器来检测非法的修改操作
61 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
运算符
运算符+ , - , * , / , % ,…++ , -- ,==, >, <, >=, <=, !=
!, &&, ||
& | ^ ~ << >>
结合性优先级 : see table 3-1 in page 35 in the recommended book 1.
62 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
运算符的使用
if ( demo = 2 ) 与 if (demo == 2 )
if ( 2== demo ) //左值与右值。
if ( demo != 2 ) 与 if ( demo =! 2 )
63 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
运算符的优先级
int a=8,b=4,c=5;
cout << (a%b ? b : c);
cout << a%b ? b:c;
64 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
变量的赋值
赋值表达式变量的初始化一次声明多个变量声明并初始化变量
65 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
无符号类型的值
无符号整数类型的回绕
unsigned short int snum;
snum = 65535;
cout << "snum=" << snum << endl;
snum = snum + 1;
cout << "snum=" << snum << endl;
66 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
有符号类型的值
有符号整数类型的回绕
int inum = 2147483647;
cout << "inum = " << inum << endl;
inum = inum + 1;
cout << "inum = " << inum << endl;
67 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
常用类型的取值范围
常用类型的取值范围
int i = 65535;
int j = 65535;
cout << i*j/9 << endl;
68 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习
为表示如下数据,应该使用什么类型的变量:年龄姓名 工资 电话号码身份证号码 西三环到东三环的距离
69 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 bin.cc
#include <iostream>
using namespace std;
int main( )
{
int a = 10;
cout << "Please enter a number:" << endl;
cin >> a;
unsigned int r;
int k;
unsigned int j;
char str[33];
memset(str, '0', 33);
str[32]='\0';
r = a;
int i = 32;
70 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 bin.cc
do {
j = r;
r = r/2;
k = j - r * 2;
if (k)
str[--i] = '1';
else
str[--i] = '0';
} while(r != 0);
cout << str << endl;
}
71 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
枚举类型
enum color{RED, GREEN, BLUE, WHITE, BLACK};
color tvColor = GREEN;
Enum constant variable does not need memory allocation.
The default value in Enum is: 0, 1, 2, 3, 4….
Specify the element values: enum color {RED=100, GREEN=200, BLUE, WHITE=300, BLACK=400}
72 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
表达式
左值与右值float a;
a = 5/2;
++a;
求值顺序特殊表达式 :
( ? : )逗号表达式: int a, b, c; a = 1, b=a=2, c=b+3;
73 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
表达式的求值顺序
求值顺序副作用
74 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
表达式的左值与右值
int a, b, c,d;
int e = (a = 1, b = a, c = a+b, d = c + 5);
(a = 1, b = a, c = a+b, d = c + 5) = 8;
e = (a = 0, b = a + 5, b+2);
(a = 0, b = a + 5, b+2) = 9; //ohps …, you may get problem...
75 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 comma.cc
#include <iostream>
using namespace std;
int main( )
{
int a, b, c,d;
int e = (a = 1, b = a, c = a+b, d = c + 5);
(a = 1, b = a, c = a+b, d = c + 5) = 8;
cout <<"d=" << d << endl;
}
76 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序语句
控制语句表达式语句空语句语句块
77 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
控制语句
条件判断语句if ( ) { … }
if ( ) {…} else {…}
循环控制语句while( ) { … }
do { … } while( );
for ( ) { … }
多路选择语句switch( ) { case: }
78 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
循环语句
for 语句do…while 语句while 语句break 语句continue 语句
79 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
分支语句
switch 语句switch(ss) {
case 1:
…
break;
case 2:
…
break;
default:
break;
};
80 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
循环语句程序例子 chengFa.cc
编写一个程序,打印出乘法口诀表分别使用 for 语句, do…while 语句, while 语句来实现
The output is:
1x1=11x2=2, 2x2=41x3=3, 2x3=6, 3x3=91x4=4, 2x4=8, 3x4=12, 4x4=161x5=5, 2x5=10, 3x5=15, 4x5=20, 5x5=251x6=6, 2x6=12, 3x6=18, 4x6=24, 5x6=30, 6x6=361x7=7, 2x7=14, 3x7=21, 4x7=28, 5x7=35, 6x7=42, 7x7=491x8=8, 2x8=16, 3x8=24, 4x8=32, 5x8=40, 6x8=48, 7x8=56, 8x8=641x9=9, 2x9=18, 3x9=27, 4x9=36, 5x9=45, 6x9=54, 7x9=63, 8x9=72, 9x9=81
81 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 year.cc
This is your assignment.
判断输入的年份是否是闰年。
82 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
83Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 3
84 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数
什么是函数函数的基本要素
参数返回值
函数的声明与定义形参与值参函数的调用
85 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
定义函数
< 返回类型 > 函数名 ( <参数表 > …){…return …
}<参数表 ><参数类型 > <参数名称 >
86 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数定义的例子#include <iostream>
using namespace std;
void disp(char str[ ] )
{
cout << "This is your string: " << str << endl;
}
int main( )
{
char course1[ ] = "C++";
char course2[ ] = "Java";
char course3[ ] = "Oracle";
char course4[ ] = "UNIX";
disp( course1 );
disp( course2 );
}
87 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数声明
< 返回类型 > 函数名 ( <参数表 > …);void disp( char* );
float average(int, int);
float average(int a, int b);
为什么需要函数声明?
88 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
调用函数
函数的形参函数的调用过程
填入值参获得返回值
89 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
栈的技术简介
栈的工作原理函数的调用与栈
90 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
栈的原理
i = f1( );j = f2( );cout << i << endl;cout << j << endl;
cout << f1( ) << endl; cout << f2( ) << endl;
#include <iostream>using namespace std;int f1();int f2();
int main( ){
int i, j;i = f1( );j = f2( );cout << i << endl;cout << j << endl
}int f1( ){
int n = 5000;return n;
}int f2( ){
int n;return n;
}
91 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
变量的作用域
局部变量与全局变量
92 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
默认参数
函数的形参可以指定默认值必须从右到左指定参数的默认值函数在调用时,是按从左到右的顺序在匹配参数
93 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用默认参数的函数例子
enum Sex{MALE, FEMALE};
void disp(char *name, Sex gender=MALE);
如果在函数声明中指定了默认值,则在函数定义时不能再指定
94 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
内联函数
提高程序运行效率内联函数的定义
inline int isnumber(char ch)
{
return ((ch>=‘0’ && ch<=‘9’) ? 1 : 0);
}
必须先定义,不支持函数原形(声明)不支持结构控制语句
95 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
递归函数
一个函数调用它自己 如何正确的递归
必须有结束的条件 并且该条件一定能够满足
96 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用与不使用递归的例子程序
编写一个程序 bigsum.cc ,使用一个函数来求 n的值 :
#include <iostream>using namespace std;int bigsum(int a){ if(a == 0) return 0; return a + bigsum(a - 1);}int main(){ int n; cout << "Please input a number: "; cin >> n; int m = bigsum(n); cout << "The sum is: " << m; cout << endl;}
97 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 nbang.cc
使用递归函数,编写一个程序来求 n! 的值 :
This is your assignment…
98 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数的重载
C++ 中的函数可以重载什么是函数的重载 :
对于在不同类型上作不同运算而又用同样的名字的情况,称为重载。函数重载的注意事项 :
重载函数至少在参数个数,参数类型, 或参数顺序上有所不同。
99 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数重载的例子
求两个数的平均值double Average(int, int);
double Average(float, float);
double Average(double, double);
double Average(long, long);
100 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
思考题
在一个程序中定义了这两个函数会怎样?int Area(int width, int length=1);
int Area(int size);
101 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Area.cc source code
#include <iostream>
using namespace std;
int Area(int width, int length = 1)
{
return width * length;
}
int Area(int size) // int Area(int size, int leng) is not allowed
{
return size * size;
}
int main( )
{
cout << Area(3, 5) << endl; //set length = 5 instead.
cout << Area(10) << endl; //is this ok?
}
102 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数参数的 const 限定
可以使用 const 限定词来修饰形参以保护实参不被修改。const 形参的意义
#include <iostream>
using namespace std;
void disp(const int I)
{
cout << I << endl;
I = 100; // think about this.
}
int main( )
{
disp(50);
}
103 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序的结构
多文件结构外部变量与内部变量变量的作用域与可见性头文件静态全局变量静态函数
104 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
多文件结构
按不同的功能模块将程序的源代码划分在多个文件中不同源文件之间可以共享变量声明与类型定义C++ 多文件的划分原则
105 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
外部变量与内部变量
存储类: auto, extern, register, static, volatile.
什么是外部变量什么是内部变量
106 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
变量的作用域与可见性
局部变量的作用域静态局部变量的作用域全局变量的作用域外部变量的作用域常量的作用域
107 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
头文件
头文件的作用如何组织头文件头文件的使用编译选项
108 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
静态全局变量
何为静态全局变量只在本源文件中可用
109 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
静态函数
定义静态函数只在本源文件中可用
110 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
改写 bigsum.cc 与 nbang.cc 程序
将 bigsum.cc 与 nbang.cc改写成多文件结构,每个文件只能有一个函数
111 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
改写 bigsum.cc 与 nbang.cc 程序
分别将前面的函数改为静态函数,再次编译并运行所有的程序
This is your assignment…
112 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 hash.cc
#include <iostream>
using namespace std;
int main( )
{
char line[100];
cout << "Please enter a string:" << endl;
cin >> line;
int ch = 0;
for(int i=0; i<strlen(line); i++)
ch += line[i];
cout << "The hash of your string is : " << ch << endl;
}
113 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 mywc.cc
输入一行文字,统计单词的个数。为了输入的时候能包含空格,程序使用了 getline 函数。
#include <iostream>
using namespace std;
int main( )
{
cout << "Please enter a line:" << endl;
char line[120];
int cnt = 0;
cin.getline(line, 120);
int i = 0;
114 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 mywc.cc
while (i<strlen(line))
{
if (line[i] != ' ')
{
cnt ++;
while ((line[i] != ' ') && (i < strlen(line)) )
{
i++;
}
}
i ++;
}
cout << "Total " << cnt << " words." << endl;
}
115 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
116Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 4
117 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
复杂数据类型
数组结构指针
118 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
数组 1
由若干个同类型变量组成的集合数组的声明< 元素类型 > 数组名 [元素个数 ];
下标是数组元素到开始的偏移量数组下标从 0 开始char buf[4]; buf[0]
buf[1]
buf[2]
buf[3]
119 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
数组 2
数组在声明时,元素个数必须是常量或常量表达式char buf[10];
int I;
char buf[I]; //???
int I = 10;
char buf[I]; //???
const int i = 10;
char buf[i];
char buf[i+1];
120 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
数组 3
如果数组的声明带有初始化,可以直接对整个数组赋值访问数组元素,使用下标操作符 [ ]
int iA[10];
iA[0] = 0;
iA[1] = 1;
int I = 0;
I = iA[0] + iA[1];
121 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
数组的初始化
在声明的时候就初始化int iA[5] = {0,1,2,3,4};
int iB[ ] = {1,2,3};
使用赋值语句初始化数组iA[0] = 0;
iA[1] = 1;
数组的边界问题int iC[5];
iC[10] = 100; //run time ???
Question: does C++ compiler have array bound checking?
122 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
数组程序例子
编写一个程序,从键盘接受一个字符串,将该字符串颠倒顺序,然后打印出来…
123 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 findmax.cc
#include <iostream>
using namespace std;
int main( )
{
int iA[ ] = {103, 5, 68, 115, 32, 23, 66, 599, 38, 444};
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < i; j++)
{
int temp;
if(iA[i] < iA[j])
//if(iA[i] < iA[j])
{
temp = iA[i];
iA[i] = iA[j];
iA[j] = temp;
}
}
}
cout << "The bigNumber is: " << iA[9] << endl;
}
124 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
多维数组
二维数组与多维数组 :
int iA[5][10];
int iB[2][3] = { {1,2,3}, {4,5,6}};
int iC[2][4][6];
多维数组的初始化仅有第一个维数可以省去
int iB[ ][3] = { {1,2,3}, {4,5,6}, {7,8,9}};
125 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
数组练习程序 mdim.cc
#include <iostream>
using namespace std;
int maximum(int [][4], int, int);
int main ( )
{
int sg[3][4] = { {68,77,73,86},
{87,96,78,89},
{90, 70, 81, 86}};
cout << "the max grade is " << maximum(sg, 3,4) << endl;
}
int maximum(int grade[ ][4], int row, int col)
{
int max = grade[0][0];
for (int i=0; i < row; i ++)
for (int j=0; j< col; j++)
if(grade[i][j] > max)
max = grade[i][j];
return max;
}
126 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构 1
将不同类型的相关数据信息组织在一起是用户自定义的类型
需要先声明类型的定义才能使用结构与数组的区别
数组只是同一个数据类型的聚集 数组本身不是一个新的数据类型
127 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构 2
struct < 结构名 > {
< 成员类型 > < 成员变量名 >;
< 成员类型 > < 成员变量名 >;
< 成员类型 > < 成员变量名 >;
…
} ( 结构变量名 );
struct Person {
char name[20];
unsigned long id;
float salary;
char address[200];
} p1, p2;
128 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构的赋值 1
通过取成员操作( . )来引用结构变量的元素Person p1 = { "G.W Bush",
1000010,
1.5 ,
"ZhongGuanChun, Beijing, China"};
strcpy(p1.name, "G.W Bush");
p1.id = 1000010;
p1.salary = 1.5;
strcpy(p1.address, "ZhongGuanChun, Beijing, China");
129 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构的赋值 2
结构赋值的例子Person p1 = { "G. W Bush",
1000010,
1.5 ,
"ZhongGuanChun, Beijing, China"};
Person p2 = p1;
130 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构的存储模式 1
每一个成员都有自己的存储空间
对每一个成员的操作都是独立的,各元素间不会相互影响
name
id
salary
131 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构的存储模式 2
#include <iostream>using namespace std;struct Person {
char name[20];unsigned long id;float salary;
};int main( ){
Person p1 = {"Zhang Weilong", 1000101, 32};cout << "&p1=" << &p1 << endl;cout << "&p1.name=" << &p1.name << endl;cout << "&p1.id=" << &p1.id << endl;cout << "&p1.salary=" << &p1.salary << endl;
}
132 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
What are pointers for ?
Accessing array elements.
Passing arguments to a function when the function needs to modify the original argument.
Passing arrays and strings to functions.
Obtaining memory from the system.
Creating data structures such as linked lists.
133 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Pointer, address, variable
int theVariable =5;
int * pPointer = & theVariable;
5
2000
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010address
theVariable
pPointer
134 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针 1
编译器为变量与常量分配存储空间任何存储空间都用地址来表示任何变量 /常量都有地址一个变量的地址也是一个有意义的值变量地址也可进行运算这个值也可以用另一个变量来存储这 "另一个 "变量的类型就是指针类型
135 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针 2
指针就是用来存储其他变量的地址的变量指针变量自己也有地址指针是有类型的指针的类型要跟它所指向的变量的类型一致
整数指针,浮点数指针
136 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
理解指针的例子程序 addr.cc
定义下面的变量,分别输出它们的值与他们的存储地址
int iVal1 = 1;
int iVal2 = 2;
double dVal1 = 1.1;
double dVal2 = 2.2;
137 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针的定义
< 数据类型 > *<指针变量名 >;
int* ip;
const int * icp;
char * str;
NULL 指针
138 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针的操作
取地址操作符 &
int * ip;
int i = 89;
ip = & i;
引用指针指向的变量 *获得该指针所指向的变量
int j = 0; j = *ip; cout << j;
139 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针的类型
整数型变量int iVal;
iVal = 10;
整数指针性变量int *iPtr;
iPtr = & iVal;
整数指针变量的地址int **ipp = & iPtr;
Any data type in c++ can be a pointer type.
140 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针的使用
指针在使用前必须初始化指针的类型决定了指针所参与的运算
指针只能进行加减法运算
141 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
理解指针的例子程序 ptracc.cc
#include <iostream>using namespace std;
int main( ){ int var1 = 11; int var2 = 22; int * ptr; ptr = &var1; cout << * ptr << endl; ptr = & var2; cout << * ptr << endl; }
142 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
理解指针的例子程序 ptracc.cc
Var1 (11)
Var2 (22)
Var1 (11)
Var2 (22)
* ptr is 11
* ptr is 22
ptr
ptr
143 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针与数组
数组的本质就是数组里所有变量的首地址数组的下标操作就是针对地址
144 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针与数组的例子程序 ptr.cc
分别用数组的方式与指针的方式来操作int iv[5]
分别给他们赋初值并输出他们的值与地址 :#include <iostream>using namespace std;int j;int iv[5] = {1,2,3,4,5};int main(){ int a = 800; int i; int b = 900; int *ptr = &i; i = 500; cout << "*ptr=" << *ptr << endl; cout << "ptr=" << ptr << endl; cout << "i=" << i << endl;
145 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针与数组的例子程序 ptr.cc
cout << "&i=" << &i << endl;ptr ++;cout << "ptr=" << ptr << endl;cout << "*ptr=" << *ptr << endl;ptr = iv;cout << "ptr=" << ptr << endl;for(int i=0; i<5; i++)
cout << *(ptr+i) << ", ";cout << endl;for(int i=0; i<5; i++) cout << iv[i] << ", "; cout << endl;for(int i=0; i<5; i++)
cout << *(iv+i) << ", "; cout << endl;for(int i=0; i<5; i++)
cout << ptr[i] << ", "; cout << endl;}
146 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构指针
结构是一种数据类型结构类型也有指针结构变量 vs 结构指针变量结构指针变量的操作
结构变量用 ( . ) 操作来存取成员 结构的指针用 ( -> ) 操作来存取成员
147 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构数组
数组的元素是某一个结构类型struct Person {
char name[20];
unsigned long id;
float salary;
char address[200];
} ;
Person allPeople[100];
148 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构中的数组元素
结构中的某个元素是数组类型struct Person {
char name[20];
unsigned long id;
float salary;
char address[200];
} ;
Person Jack = {"Jack", 2L, 8000.00, "Toronto"};
149 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针作形参
利用指针在函数中传递参数
150 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 swap1.cc
#include <iostream>using namespace std;void swap(int, int);
int main( ){ int a = 3, b = 8; cout << "a= " << a << ", b = " << b << endl; swap(a,b); cout << "after swapping… \n"; cout << "a = " << a << ", b = " << b << endl;}
void swap(int x, int y){ int temp = x; x = y; y = temp;}
151 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 swap2.cc
#include <iostream>using namespace std;void swap(int *, int * );int main( ){ int a = 3, b = 8; cout << "a= " << a << ", b = " << b << endl; swap(&a, &b); cout << "after swapping… \n"; cout << "a = " << a << ", b = " << b << endl;}
void swap(int * x, int * y){ int temp = * x; * x = * y; * y = temp;}
152 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 date.cc
This is your assignment…
要求用结构、指针。
153 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
154Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 5
155 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
内存管理与引用
C++ 的内存管理引用
156 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用动态内存
内存的申请与释放
157 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
堆与内存管理
堆空间简介堆空间的管理
new/delete
158 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
New 操作
int * ip;
ip = new int;
float *fp;
fp = new float;
int *ipA = new int[5];
int * pA[5];
for(int j=0; j<5; j++)
pA[j] = new int[10];
159 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Delete 操作
delete ip;
delete fp;
delete [ ] ipA;
for(int j=0; j<5; j++)
delete [ ] pA[j];
160 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
含指针的结构变量的赋值
如果结构中含有指针成员,使用了动态空间
161 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
通过指针传递参数
函数的形参类型可以是指针通过指针来传递参数
162 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 ptrsort.cc
#include <iostream>using namespace std;
int main( ){ void bsort(int*, int); const int N =10; int data[N]= {37,84,62,91,11,65,57,28,19,49}; int *arr = new int[N]; for( int i=0; i<N; i++ ) arr[i] = data[i]; bsort(arr, N); for(int j=0; j<N; j++) cout << arr[j] << " "; cout << endl; delete[] arr; }
163 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
练习程序 ptrsort.cc
void bsort(int* ptr, int n){ void order(int *, int *); int j,k; for(int j=0; j<n-1; j++) for(k=j+1; k<n;k++) order(ptr+j, ptr+k);}//-------------------------------------------------void order(int* numb1, int * numb2){ if(*numb1 > * numb2) { int temp = * numb1; *numb1 = * numb2; *numb2 = temp; }}
164 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
危险的指针用法
使用 NULL 指针的内容使用没有初始化的指针变量使用已经被 delete 的指针内容函数返回局部变量的地址由函数申请的堆空间,而由调用者来释放
165 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数指针
调用一个函数 函数都有地址,存放在内存的代码区 (code).
函数指针 函数指针指向代码区中的某个函数。
函数指针的声明int (*func) (char a, char b);
int * func (char a, char b); //how about this one?
166 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数指针
func is a pointer that points to a function. Example:
int fn1 (char a, char b); int* fn2(char x, char y); int fn3(int a);
int (* fp1) (char a, char b); int ( * fp2) (int s);
fp1 = fn1; //okfp1 = fn2; //errorfp2 = fn3; // okfp2 = fp1; //errorfp1 = fn2(‘a’, ‘b’); //error.fp1(‘a’, ‘b’); //ok
167 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数指针 funcptr.cc
#include <iostream>using namespace std;
int swap(int *a, int *b){ int t; t = *a; *a = *b; *b = t;}
int main(){ int i = 100; int j = 200; int m = 300; int n = 400; cout << "i= " << i << endl;
168 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数指针 funcptr.cc
cout << "j= " << j << endl;
swap(&i, &j); cout << "(Swap)i= " << i << endl; cout << "(Swap)j= " << j << endl;
int (*func)(int *, int *); func = swap; func(&m, &n); cout << "(Func)m= " << m << endl; cout << "(Func)n= " << n << endl;}//end of funcptr.cc
169 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
指针的指针
可以存在多层的指针int iNum;
int *ptr;
int **pptr;
170 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
void 指针
void * ptr;
171 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
const 与指针
普通指针:指向的对象的值可以改变,指针的值也可改变int *p;
常量指针:指针可以指向不同的对象,但其指向的对象的值不能变
const int *p;
指针常量:指针本身是常量,只能指向固定的对象,但其指向的对象的值可改变
int * const p;
必须初始化常量指针指向常量
const int * const p;
必须初始化
172 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
引用
引用是一个变量的别名引用的声明
int iVal;
int & iRef = iVal;
引用的使用声明的时候就必须初始化 引用不能重新赋值 ( 不能重新绑定为另一个新对象的别名 )
173 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
引用的例子程序 myRef.cc
#include <iostream>
using namespace std;
int main()
{
int iVal = 100;
cout << "iVal=" << iVal << endl;
cout << "&iVal=" << &iVal << endl;
int &iRef = iVal;
cout << "iRef = " << iRef << endl;
cout << "&iRef = " << &iRef << endl;
iRef = 200;
cout << "iVal=" << iVal << endl;
cout << "iRef = " << iRef << endl;
}
174 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
引用的重新赋值 myRef2.cc
为引用重新赋值int iA;
int &iRef = iA;
iRef = 5;
cout << "iA=" << iA << "; &iA = " << &iA << endl;
cout << "iRef=" << iRef << "; &iRef = " << &iRef << endl;
int iB = 9;
iRef = iB;
cout << "iA=" << iA << "; &iA = " << &iA << endl;
cout << "iRef=" << iRef << "; &iRef = " << &iRef << endl;
cout << "iB=" << iB << "; &iB = " << &iB << endl;
175 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
通过引用来传递参数
函数的形参可以是引用通过引用来传递参数
176 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
引用作为函数的参数 ref1.cc
#include <iostream>using namespace std;void disp(int &i){ cout << "i=" << i << "; &i=" << &i << endl;}int main(){ int a = 100, b = 200; cout << "a=" << a << "; &a=" << &a << endl; disp(a);
cout << "b=" << b << "; &b=" << &b << endl; disp(b);}
177 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用引用的 swap.cc 程序
#include <iostream>using namespace std;void swap(int &, int & );
int main( ){ int a = 3, b = 8; cout << "a= " << a << ", b = " << b << endl; swap(a, b); cout << "after swapping… \n"; cout << "a = " << a << ", b = " << b << endl;}
void swap(int & x, int & y){ int temp = x; x = y; y = temp;}
178 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数返回一个类型的引用
函数可以返回任何类型的引用如果返回的引用对应于一个局部变量?
179 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数返回引用 ref3.cc
指出下列程序的输出结果分别是什么#include <iostream>using namespace std;int & getInt(const int v){
int t = v;return t;
}int main(){
int n = getInt(888);int m = getInt(999);cout << "n = " << n << endl;cout << "m =" << m << endl;
}
180 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
堆中指针变量的引用 testDelete.cc
看看下列程序有无问题
#include <iostream>using namespace std;int & getInt(const int v){
int *p = new int(v);return *p;
}int main(){
int &n = getInt(888);cout << n << endl;
int *pp = &n; delete pp;
}
•如何释放堆中的空间?
•int* p = & n;
•delete p;
181 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
引用的使用
尽量使用引用来传递参数尽量使用 const来保护引用尽量使用引用来代替指针危险的引用方法
返回一个局部变量的引用
182 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
183Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 6
184 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
面向对象的 C++ 编程
类构造函数与析构函数类成员的屏蔽与作用域面向对象的程序设计方法
185 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
新的类型
类一个类似于结构的类型
类的声明class 类名 {
<成员定义 >;…
};
186 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构的定义
struct Person {
char name[30];
unsigned int age;
char address[100];
float salary;
};
187 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构的操作 1
void setName(Person *pP, char* str) {
strcpy(pP->name, str);
}
void setAge(Person *pP, unsigned int yr) {
pP->age = yr;
}
void setSalary(Person *pP, float s) {
pP->salary = s;
}
void setAddress(Person *pP, char* addr) {
strcpy(pP->address, addr);
}
188 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
结构的操作 2
void disp(Person *pP )
{
cout << "Name:" << pP->name << endl;
cout << "Age:" << pP-> age << endl;
cout << "Address:" << pP-> address << endl;
cout << "Salary:" << pP->salary << endl;
}
189 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用结构变量的 person.cc
#include <iostream>
…
int main( )
{
Person Jack = { "Jack", 30, "Beijing China", 8000.0};
disp( &Jack );
Person somebody;
setName( &somebody, "Lisa");
setAge( &somebody, 20);
setAddress( &somebody, "Toronto, Canada");
setSalary( &somebody, 6000.0);
disp( &somebody );
}
190 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
封装好的结构 1
struct Person {
char name[30];
unsigned int age;
char address[100];
float salary;
void setName(char*);
void setAge(unsigned int);
void setAddress(char*);
void setSalary(float);
void disp( );
};
191 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
封装好的结构 2
void Person::setName(char* str) {
strcpy(name, str);
}
void Person::setAge(unsigned int yr) {
age = yr;
}
void Person::setSalary(float s) {
salary = s;
}
void Person::setAddress(char* addr) {
strcpy(address, addr);
}
192 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
封装好的结构 3
void Person::disp( )
{
cout << "Name:" << name << endl;
cout << "Age:" << age << endl;
cout << "Address:" << address << endl;
cout << "Salary:" << salary << endl;
}
193 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用封装后的结构变量的 person.cc
#include <iostream>
…
int main( )
{
Person Jack = { "Jack", 30, "Beijing China", 8000.0};
Jack.disp( );
Person somebody;
somebody.setName( "Lisa" );
somebody.setAge( 20 );
somebody.setAddress( "Toronto, Canada" );
somebody.setSalary(6000.0);
somebody.disp( );}
194 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
仍然存在的问题
#include <iostream>
…
int main( ){
Person Jack = { "Jack", 30, "Beijing China", 8000.0};Jack.disp( );
Jack.salary = 1000.00;Jack.disp( );
}
195 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
如何实现数据隐藏
引入 class 类型对数据成员进行保护
增加存取范围私有成员 private
保护成员 protected
公共成员 public
196 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
定义类来实现数据隐藏
class Person {private:
char name[30];unsigned int age;char address[100];float salary;
public:void setName(char* str);void setAge(unsigned int yr);void setAddress(char *str);void setSalary(float yuan);void disp( );
};
197 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
类成员的作用域属性
在 C++ 中, class 与 struct 的区别 struct 的缺省作用域为 public
class 的缺省作用域为 private
private 的数据成员只能被类的成员函数所使用
198 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用对象的 person.cc
#include <iostream>…int main( ){
Person somebody; somebody.setName( "Lisa" ); somebody.setAge( 20 ); somebody.setAddress( "Toronto, Canada" ); somebody.setSalary(6000.0);
somebody.disp( );}
199 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
类的声明与类的定义
类的声明 一般在头文件中声明类的所有成员声明类的成员的属性声明所有接口(公共函数成员)的签名(格式)
类的定义 一般放在程序文件( .cc文件)中 定义类的所有成员函数的具体实现方法
200 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
对象
对象是类的一个实例 Person 是一个 class ,它是一个数据类型 somebody 是一个对象,它是一个具体的变量
类是一类对象的描述 定义结构,可以声明许多变量 定义类,可以声明许多对象
201 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
增加对象初始化自己的能力
新 person.cc 程序的问题Person Jack = { "Jack", 30, "Beijing China", 8000.0};
Jack.disp( );
构造函数 一种特殊的函数没有返回类型只能作为是公共成员只能用一个固定的名字,函数名就是类的名字
202 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Person 类的构造函数
class Person {
…
public:
Person(char*, unsigned int, char*, float);
};
203 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
构造函数的特点
构造函数只在建立对象的时候自动被调用一次构造函数必须是公共的,否则无法生成对象构造函数只负责为自己的类构造对象
204 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
在构造函数中初始化变量
Person::Person( ) : name("Jack"), age(30)
{
…
}
205 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
有构造函数的例子 simpleClass.cc
#include <iostream>using namespace std;class A { int a; public:
A( ) { cout << "A( )" << endl;}A(const int & o) //constructor overload
{ a = o; cout << "A(const int &)" << endl; }};int main( ){ A o = A( ); int a=100; A p(a);}
206 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
析构函数
与构造函数相对应 与构造函数的作用相反 析构函数的形式
~类名 ( ){
…}
207 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
析构函数的特点
固定的函数名称~类名 ( )
没有返回类型没有参数不可以重载一般由系统自动的调用
208 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 默认的构造函数
C++ 自动给每一个 class加上一个构造函数这个构造函数没有任何参数这个构造函数也不做任何操作如果用户自己定义了一个构造函数, C++就不再提供默认的构造函数了
209 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 默认的析构函数
C++ 自动给每一个 class加上一个析构函数析构函数不能有任何参数这个析构函数也不做任何操作如果用户自己定义了一个析构函数, C++就不再提供默认的析构函数了
210 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
构造函数的作用
提供内部成员变量的初始化功能完成对象的初始化
内存管理实现对象的拷贝功能
211 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
构造函数的调用
class A {
public:
void disp( );
};
A a, *b = new A, *c = new A( ), *d = new (A); //are they all right?
a = A( );
A aa( ); //won’t instantiate any object.
212 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
构造对象的顺序
局部与静态局部对象,以声明的顺序构造 静态对象只被构造一次
全局对象在 main 之前构造全局对象的构造无特殊顺序
数据成员对象,以声明顺序构造
213 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
析构函数的作用
与构造函数相反释放资源
内存管理析构函数的调用
什么时候析构函数被调用
214 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
析构函数的例子
#include <iostream>
using namespace std;
class Str{
int len;
char *string;
public:
Str(char* = "default");
~Str( );
};
Str::Str(char *s)
{
string =
new char[len=strlen(s)+1];
strcpy(string, s);
}
Str::~Str()
{
cout << "Destructor of " << string
<< endl;
delete []string;
}
int main( )
{
Str *words = new Str[3];
delete []words;
}
215 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
析构函数的直接调用
析构函数可以被直接调用#include <iostream>
…
int main( )
{
…
Person p;
p.~Person( );
…
}
216 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
对象指针
定义的类就是一个数据类型对象与对象指针new 与 delete
对象指针的使用
217 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
This成员
this
this 的使用
218 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
对象的引用
对象也可以有别名
219 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Person对象的指针与引用
……
person::person(const person& p)
{
strcpy(this->name, p.name);
this->age = p.age;
strcpy(this->address, p.address);
this->gender = p.gender;
}
……
220 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
面向对象的程序设计方法1
自然界就是由许多的对象组成 自然界中的任何一个实体都可以看作一个对象非实体也能看成某种对象(逻辑上的实体)
自然界的现象就是许许多多的同类与不同类的对象在相互作用
一个对象包含一个或多个其他的对象 一个对象使用另一个或多个对象同种或不同种的对象之间存在各种复杂的关系
221 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
面向对象的程序设计方法2
分析并分解出某个问题中的种种对象准确的描述所有对象之间的种种关系找到它们之间的所有相互作用用程序设计语言与工具来描述它们用程序开发语言来表达(实现)它们
222 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
对象的特点
对所有对象进行抽象总结名称属性 行为
用 class来表述
223 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
传统的程序设计方法
程序=数据+算法算法=函数+控制流程传统方法的特点
结构化封装,但无法隐藏 算法依赖于数据,更改与维护困难 重用性差
224 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
面向对象的方法
分析问题,找到对象抽象出对象的属性与特点划分出类确定类与类的关系用类来定义程序结构
225 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
面向对象的优点1
更好的封装 数据隐藏 操作屏蔽把特定的数据与相应的操作组合在一起把可见的与不可见的部分很理想的分离开来
C++ 语言中封装是由类来实现的
226 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
面向对象的优点2
继承 更好的可重用特性软件更易扩展与更可维护性
227 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
面向对象的优点3
多态最重要的面向对象特性之一突出的优点
228 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Exercises
设计一个叫做 String 的类,要求该类能够完成以下功能:(1) 构造函数能够根据实际传入的参数分配实际存储空间;缺省时为 100字节;(2) 析构函数释放该空间;(3) 编写成员函数 Assign ,可以将一个字符串赋值给该类;(4) 编写成员函数 Disp ,可以将该类的内容打印到屏幕上;(5) 编写成员函数 Replace ,用于替换某一指定的字符串;(6) 编写成员函数 Append ,用于向已有的数据后面添加数据;(7) 编写成员函数 Size ,用于得到当前数据的真实长度。编写测试程序,测试这个类。
class String{ char * str; unsigned int len;public: String(); String(const char* sz); ~String(); //Return 0 -- success, -1 Error int Assign(char *); void Disp(); //Return 0 -- success, -1 Error int Replace(char* from, char* to); //Return 0 -- success, -1 Error int Append(char*); unsigned int Size();};
229 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
230Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 7
231 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
继承和多态
什么是继承 继承与派生
继承的工作方式私有成员与保护成员构造函数与析构函数虚函数与多态多重继承与虚继承抽象数据类型
232 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
什么是继承
自动获得另一种事物的部分或者全部的东西(属性,能力)The "is a" relationship
是一种从属的关系自然界中的 "is a"关系非常普遍C++ 使用继承来表示这种关系
233 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
继承与组合
组合的概念 The "has a" relationship
是一种包含关系
234 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
继承与组合
person
student teacher
Part time studentFull time student
student "is a" kind of person.
Full time student "is a" kind of student …….
Computer
CPU Monitor
… …
Computer "has a" CPU
Computer "has a" Monitor…
235 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
继承的描述
继承是一种关系反映了对象与对象之间的联系由类与后继类来描述前者也称基类后继类也称派生类从后者的角度看称为继承从前者的角度看称为派生
236 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
继承的作用
C++ 中,继承可以让一个类自动地获得另一个类的部分或全部的属性与操作继承提高了代码的可重用性
237 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
继承的语法
class 派生类名 : <public|protected|private> 基类名 {
<派生类的成员 >;
<派生类的成员 >;
…
};
238 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
继承的例子
class Person {
…
public:
void disp( );
};
class Student : public Person {
public:
int grade;
void setGrade(int);
};
239 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
哪些东西可以继承
类成员的可见性public
private
protected
派生方式影响可见性 class 派生类名 : <public|protected|private> 父类名
240 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
覆盖
覆盖将隐藏基类的方法class Student : public Person {public:
int grade;void setGrade(int);void disp( );
};void Student::disp( ){
cout << "disp() of Student." << endl;}
调用基类的方法Person::disp( );
241 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
基类的内存模式
enum Sex{MALE, FEMALE};
class Person {
private:
char name[20];
unsigned int age;
protected:
Sex gender;
float salary;
public:
void Eat( );
void Drink( );
void Sleep( );
void Disp( );
};
name
age
gender
Eat
Drink
Sleep
salary
Disp
242 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
grade
Study
disp
派生类的内存模式 1
class Student : public Person {
private:
int grade;
public:
void Study( );
void disp( );
};
name
age
gender
Eat
Drink
Sleep
salary
disp
243 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
派生类的内存模式 2
在一个 Student 对象中,包含有一个 Person 对象那么,在 Student 对象中,有没有 Person 对象的私有数据成员存在?
unsigned int age
float salary
244 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
类继承的程序例子 mamal.cc
#include <iostream>
enum BREED { GOLDEN, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };
class Mammal
{
public:
// constructors
Mammal();
~Mammal();
//accessors
int GetAge() const;
void SetAge(int);
int GetWeight() const;
void SetWeight();
//Other methods
void Speak() const;
void Sleep() const;
protected:
int itsAge;
int itsWeight;
};
245 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
类继承的程序例子 mamal.cc
class Dog : public Mammal{public:
// ConstructorsDog();~Dog();// AccessorsBREED GetBreed() const;void SetBreed(BREED);// Other methodsvoid WagTail();void BegForFood();
protected:BREED itsBreed;
};
246 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
构造函数
构造函数的调用顺序由基类到派生类
如何向基类的构造函数传递参数容易犯的错
匹配构造函数
247 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
析构函数
析构函数的调用顺序由派生类到基类
直接调用派生类的析构函数 基类的析构函数是否也被调用 ?
248 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
哪些东西可以派生
任何一个类都可能派生出新的类原始数据类型无法派生
class A : public int {
…
};
249 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Polymorphism
多态的本质C++允许把派生类对象赋给基类的指针所有的派生类在本质上都 "is a" 基类 用基类的指针调用任何方法, C++都能找到相应的派生类的方法
250 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Polymorphism example: horse.cc
#include <iostream>using namespace std;class Horse{public:
void Gallop(){ cout << "Galloping...\n"; }virtual void Fly() { cout << "Horses can't fly.\n" ; }
private:int itsAge;
};
class Pegasus : public Horse{public:
virtual void Fly() {cout<<"I can fly! I can fly! I can fly!\n";}};
const int NumberHorses = 5;
251 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Polymorphism example: horse.cc
int main()
{
Horse* Ranch[NumberHorses];
Horse* pHorse;
int choice,i;
for (i=0; i<NumberHorses; i++)
{
cout << "(1)Horse (2)Pegasus: ";
cin >> choice;
if (choice == 2)
pHorse = new Pegasus;
else
pHorse = new Horse;
Ranch[i] = pHorse;
}
cout << "\n";
for (i=0; i<NumberHorses; i++)
{
Ranch[i]->Fly();
delete Ranch[i];
}
return 0;
}
252 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
对象指针的转换
Up casting
Down casting
253 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
对象指针的转换 dyHorse.cc
#include <iostream>using namespace std;//enum TYPE { HORSE, PEGASUS };class Horse{public:
virtual void Gallop(){ cout << "Galloping...\n"; }private:
int itsAge;};class Pegasus : public Horse{public:
virtual void Fly() {cout<<"I can fly! I can fly! I can fly!\n";}};const int NumberHorses = 5;
254 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
对象指针的转换 dyHorse.cc
int main(){
Horse* Ranch[NumberHorses];Horse* pHorse;int choice,i;for (i=0; i<NumberHorses; i++){
cout << "(1)Horse (2)Pegasus: ";cin >> choice;if (choice == 2)
pHorse = new Pegasus;else
pHorse = new Horse;Ranch[i] = pHorse;
}cout << "\n";
255 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
对象指针的转换 dyHorse.cc
for (i=0; i<NumberHorses; i++){
Pegasus *pPeg = dynamic_cast< Pegasus *> (Ranch[i]); //down cast
if (pPeg)
pPeg->Fly();
else
cout << "Just a horse\n";
delete Ranch[i];
}
return 0;
}
256 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚函数 1
什么是虚函数为什么要使用需函数
257 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚函数 2
虚函数的声明与定义virtual void disp( );
虚函数的工作原理 V table
258 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚函数的使用
构造函数不能是虚函数如果类中有任何一个成员函数是虚函数,那么析构函数应为虚函数如果一个类肯定被用作其他派生类的基类,尽可能使用虚函数
259 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚函数使用 example vdog.cc
#include <iostream>using std::cout;class Mammal{public:
Mammal():itsAge(1) { cout << "Mammal constructor...\n"; }virtual ~Mammal() { cout << "Mammal destructor...\n"; }void Move() const { cout << "Mammal move one step\n"; }virtual void Speak() const { cout << "Mammal speak!\n"; }
protected:int itsAge;
};class Dog : public Mammal{public:
Dog() { cout << "Dog Constructor...\n"; }virtual ~Dog() { cout << "Dog destructor...\n"; }void WagTail() { cout << "Wagging Tail...\n"; }void Speak()const { cout << "Woof!\n"; }void Move()const { cout << "Dog moves 5 steps...\n"; }
};
260 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚函数使用 example vdog.cc
int main()
{
Mammal *pDog = new Dog;
pDog->Move();
pDog->Speak();
delete pDog;
return 0;
}
261 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
多重继承
C++支持从多个基类中派生出一个新的类多重继承的对象的构造顺序多重继承同名时的歧义解析
262 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
多重继承的例子
Horse Bird
Pegasus
263 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
多重继承的例子 mHorse.cc
#include <iostream>
using std::cout;
using std::cin;
class Horse
{
public:
Horse()
{ cout << "Horse constructor... "; }
virtual ~Horse()
{ cout << "Horse destructor... "; }
virtual void Whinny() const
{ cout << "Whinny!... "; }
private:
int itsAge;
};
class Bird
{
public:
Bird()
{ cout << "Bird constructor... "; }
virtual ~Bird()
{ cout << "Bird destructor... "; }
virtual void Chirp() const
{ cout << "Chirp... "; }
virtual void Fly() const
{
cout << "I can fly! I can fly! I can fly! ";
}
private:
int itsWeight;
};
264 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
多重继承的例子 mHorse.cc
class Pegasus : public Horse, public Bird{public:
void Chirp() const { Whinny(); }Pegasus()
{ cout << "Pegasus constructor... "; }~Pegasus()
{ cout << "Pegasus destructor... "; }};const int MagicNumber = 2;int main(){
Horse* Ranch[MagicNumber];Bird* Aviary[MagicNumber];Horse * pHorse;Bird * pBird;int choice,i;
for (i=0; i<MagicNumber; i++){
cout << "\n(1)Horse (2)Pegasus: ";cin >> choice;if (choice == 2)
pHorse = new Pegasus;else
pHorse = new Horse;Ranch[i] = pHorse;
}cout << "\n";
for (i=0; i<MagicNumber; i++){
cout << "\nRanch[" << i << "]: " ;Ranch[i]->Whinny();delete Ranch[i];
}
265 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
多重继承的例子 mHorse.cc
for (i=0; i<MagicNumber; i++){
cout << "\n(1)Bird (2)Pegasus: ";cin >> choice;if (choice == 2)
pBird = new Pegasus;else
pBird = new Bird;Aviary[i] = pBird;
}
for (i=0; i<MagicNumber; i++){
cout << "\nAviary[" << i << "]: " ;Aviary[i]->Chirp();Aviary[i]->Fly();delete Aviary[i];
}return 0;
}
266 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
多重继承的麻烦
horse bird
pegasus
animal
pPeg -> GetAge() ?
267 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚继承
pegasus
horse bird
animal
virtual virtual
268 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚继承的例子 vHorse.cc
#include <iostream>using namespace std;typedef int HANDS;enum COLOR { Red, Green, Blue, Yellow, White, Black, Brown } ;class Animal // common base to both horse and bird{public:
Animal(int);virtual ~Animal() { cout << "Animal destructor...\n"; }virtual int GetAge() const { return itsAge; }virtual void SetAge(int age) { itsAge = age; }
private:int itsAge;
};
Animal::Animal(int age):itsAge(age){
cout << "Animal constructor...\n";}
269 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚继承的例子 vHorse.cc
class Horse : virtual public Animal{public:
Horse(COLOR color, HANDS height, int age);virtual ~Horse() { cout << "Horse destructor...\n"; }virtual void Whinny()const { cout << "Whinny!... "; }virtual HANDS GetHeight() const { return itsHeight; }virtual COLOR GetColor() const { return itsColor; }
protected:HANDS itsHeight;COLOR itsColor;
};Horse::Horse(COLOR color, HANDS height, int age):Animal(age),itsColor(color),itsHeight(height){
cout << "Horse constructor...\n";}
270 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚继承的例子 vHorse.cc
class Bird : virtual public Animal{public:
Bird(COLOR color, bool migrates, int age);virtual ~Bird() {cout << "Bird destructor...\n"; }virtual void Chirp()const { cout << "Chirp... "; }virtual void Fly()const { cout << "I can fly! I can fly! I can fly! "; }virtual COLOR GetColor()const { return itsColor; }virtual bool GetMigration() const { return itsMigration; }
protected:COLOR itsColor;bool itsMigration;
};Bird::Bird(COLOR color, bool migrates, int age):Animal(age),itsColor(color), itsMigration(migrates){cout << "Bird constructor...\n";}
271 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚继承的例子 vHorse.cc
class Pegasus : public Horse, public Bird
{
public:
void Chirp()const { Whinny(); }
Pegasus(COLOR, HANDS, bool, long, int);
virtual ~Pegasus() {cout << "Pegasus destructor...\n";}
virtual long GetNumberBelievers() const
{ return itsNumberBelievers; }
virtual COLOR GetColor()const { return Horse::itsColor; }
private:
long itsNumberBelievers;
};
272 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚继承的例子 vHorse.cc
Pegasus::Pegasus(
COLOR aColor,
HANDS height,
bool migrates,
long NumBelieve,
int age):
Horse(aColor, height,age),
Bird(aColor, migrates,age),
Animal(age*2),
itsNumberBelievers(NumBelieve)
{
cout << "Pegasus constructor...\n";
}
273 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
虚继承的例子 vHorse.cc
int main()
{
Pegasus *pPeg = new Pegasus(Red, 5, true, 10, 2);
int age = pPeg->GetAge();
cout << "This pegasus is " << age << " years old.\n";
delete pPeg;
return 0;
}
274 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
抽象数据类型
C++支持抽象数据类型任何一个抽象类都是 ADT
ADT 的使用从抽象类派生新的类 (ADT can’t instantiate object directly)
确保实现所有的纯虚函数 ( virtual void Draw() = 0; )
275 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Exercises
编写一个存储艺术作品的程序。艺术作品分为三类 :Painting、Music和Chamber, Chamber是Music 中的一类。要求如下所述。①每件作品都要标明著者、作品标题、作品诞生年份及其所属分类。② Painting 类要求显示画的宽和高等尺寸信息。③ Music 类要求显示能够代表其内容的关键信息 , 例如 "D Major" 。④ Chamber 类要求显示其中包括的演奏人员的数目。
编写测试程序测试
设计一个程序,有一个汽车类 vehicle ,它具有一个需要传递参数的构造函数,类中的数据成员包括 :车轮个数 wheels 和车重 weight 作为保护成员 : 小车类 car 是它的派生类,其中包含载人数 passengers;卡车类 truck是 vehicle的派生类,其中包含载人数 passengers 和载重量 payload 。每个类都有相关数据的输出方法。
编写测试程序测试
276 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
277Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 8
278 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
More about class in C++
友员静态成员成员函数的重载
拷贝构造函数 运算符 类型转换操作符 重载 new与 delete
流操作符
279 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Static Members
什么是静态成员static修饰符
静态成员的特点
280 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
静态数据成员
所有的同一类对象都使用一份数据静态数据成员又称为类变量
它属于这个类,被该类的全体对象共享类变量的初始化
class Counter {
static int cnt;
};
类变量必须在 class 声明的外面单独声明,并初始化。如果不初始化,则编译器自动初始化 0
int Counter::cnt;
或int Counter::cnt = 0;
281 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
静态函数成员
公共的静态函数成员就是一个全局函数对公共的静态函数可以直接调用,不需要通过任何对象静态成员函数中不得使用非静态数据成员
282 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
静态成员的应用例子 statics.cc
#include <iostream>
using namespace std;
class Cat
{
public:
Cat(int age):itsAge(age){HowManyCats++; }
virtual ~Cat() { HowManyCats--; }
virtual int GetAge() { return itsAge; }
virtual void SetAge(int age) { itsAge = age; }
static int HowManyCats;
private:
int itsAge;
};
int Cat :: HowManyCats = 0;
void TelepathicFunction();
283 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
静态成员的应用例子 statics.cc
int main(){
const int MaxCats = 5; int i;Cat *CatHouse[MaxCats];for (i = 0; i<MaxCats; i++){
CatHouse[i] = new Cat(i);TelepathicFunction();
}for ( i = 0; i<MaxCats; i++){
delete CatHouse[i];TelepathicFunction();
}return 0;
}void TelepathicFunction(){
cout << "There are ";cout << Cat ::HowManyCats << " cats alive!\n";
}
284 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
友员
为什么需要友员 : Friend As Bridges.
什么东西可以成为友员 友员函数 友员类
285 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
友员的声明
友员函数的声明class Student {
…
friend void Register(Student&);
…
};
友员类的声明class Teacher;
class Student {
…
friend class Teacher;
};
286 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
友员的例子 friend.cc
#include <iostream>using namespace std;
class beta;class alpha{ private: int data; public: alpha(): data(3) { } friend int frifunc (alpha, beta);};class beta{ private: int data; public: beta () : data (7) { } friend int frifunc(alpha, beta);};
287 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
友员的例子 friend.cc
int frifunc(alpha a, beta b)
{ return (a.data + b.data); }
int main( )
{
alpha aa;
beta bb;
cout << frifunc(aa, bb) << endl;
return 0;
}
288 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
成员函数的重载
构造函数的重载缺省构造函数 自定义构造函数拷贝构造函数
289 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
构造函数的重载
#include <iostream>using namespace std;class Rectangle{public:
Rectangle();Rectangle(int width, int length);~Rectangle() {}int GetWidth() const { return itsWidth; }int GetLength() const { return itsLength; }
private:int itsWidth;int itsLength;
};Rectangle::Rectangle(){
itsWidth = 5;itsLength = 10;
}
290 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
构造函数的重载
Rectangle::Rectangle (int width, int length){
itsWidth = width;itsLength = length;
}int main(){
Rectangle Rect1;cout << "Rect1 width: " << Rect1.GetWidth() << endl;cout << "Rect1 length: " << Rect1.GetLength() << endl;int aWidth, aLength;cout << "Enter a width: ";cin >> aWidth;cout << "\nEnter a length: ";cin >> aLength;Rectangle Rect2(aWidth, aLength);cout << "\nRect2 width: " << Rect2.GetWidth() << endl;cout << "Rect2 length: " << Rect2.GetLength() << endl;return 0;
}
291 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Copy Constructor
当由一个已有的对象来构造一个新的对象时,需要 copy constructor
默认的对象拷贝普通类的 copy constructor
C++ 编译器会自动给每一个类加上一个如果没有使用任何动态空间,则可以使用系统的:
浅拷贝 (memcpy() will be called)
如果该类使用了任何动态分配的内存,则需要重载 copy constructor
深拷贝 (need overload copy constructor)
292 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
调用 copy constructor
类 A 的定义如下class A {
int a;
public:
A(int v = 0) : a(v) {}
};
下面分别生成对象 o1与 o2 有何不同A o1(3);
A o2 = o1;
A o1(3);
A o2;
o2 = o1;
A o2 = o1;•使用 copy constructor
A o2;o2 = o1;
•使用赋值语句
293 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
拷贝构造函数的定义
class A {
int a;
public:
A(const A&);
};
A::A(const A& o) {
a = o.a;
};
294 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
拷贝构造函数的例子
class V {int *pv;
public:V(int a) { pv = new int; *pv = a; }~V( ) { delete pv;}void disp( ) {
cout << "This=" << this << endl;cout << "pv=" << pv << endl;cout << "*pv=" << *pv << endl;
}};…V a(3);V b(5);a.disp();b.disp();
V a(3);V b = a;......*b.pv=100;a.disp( );b.disp( );
V(const V& s) {pv = new int;*pv = *s.pv;
}
295 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
自动调用构造函数
问题出现Class A{
int a;};A oa = 3;
解决办法class A {
int apublic:
A(int i) : a(i) { };};int main(){
A oa=3;
}
296 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
自动调用的局限
只会使用只含一个参数的 constructor
任何时候遇到歧义,则放弃尝试
297 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
运算符的重载
重载赋值运算符重载运算符的方法
运算符作为友员来重新定义 作为成员函数来重载
运算符操作的返回值返回 引用返回
重载转换运算符
298 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Operator=
赋值操作符的功能缺省的 operator=
299 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
缺省的 operator= 的问题
class V {int *pv;
public:V(int a) { pv = new int; *pv = a}~V( ) { delete pv;}void disp( ) {
cout << "This=" << this << endl;cout << "pv=" << pv << endl;cout << "*pv=" << *pv << endl;
}};…V a(3);V b(5);a.disp();b.disp();
V a(3);V b(5);
b = a;
a.disp( );b.disp( );
300 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Operator= 的重载
operator= 作为成员函数重载class V {
…
V& operator=(const V&);
};
V& V::operator=(const V& s)
{
…
*pv = *s.pv;
return *this;
};
301 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Operator= 重载的注意事项
可能的问题obj = obj;
解决办法if (this == &s)
return *this;
编译器会自动为一个类创建 operator=
Memberwise assignment
复杂类必须自己定义 operator=来处理堆内存的使用
302 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
异端的 operator= 重载
class Pixel{int x, y;int color;
public:Pixel(int a=0, int b=0):x(a),y(b) {color=0;}Pixel(int a, int b, int c) {
x = a; y = b; color = c;}void draw( ) {
cout << "(" << x << "," << y << ")=" << color << endl;}
};…Pixel p1(1, 2);Pixel p2(3, 5, 1);
p1.draw( );p2.draw( );
Pixel p1(1, 2);Pixel p2(3, 5, 1);
p2 = p1;p1.draw( );p2.draw( );
Class Pixel {…
Public:…
Pixel& operator=(const Pixel& s) {x = s.y; y = s.x; color = !s.color;
}};
303 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
copy constructor 与 operator=
什么时候调用 copy constructor
什么时候调用 operator =
指出下面三种写法的差别A o ;
A o;
o = A( );
A o1;
A o2 = o1;
A o;•直接调用 constructor,构造对象o
A o;o = A( );
•直接调用 constructor ,构造对象o•再构造出一个临时对象,并将该临时对象赋给 o , (operator= is called)
A o1;A o2 = o1;
•直接调用 constructor ,构造对象o1•用 o1 作参数,再调用 copy constructor 构造对象 o2
304 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
单目运算符的重载 1
operator ++ 作为友员的重载class A {
int a,b;
public:
A(int x, int y) : a(x), b(y) {}
friend A& operator ++ (A&);
};
A& operator ++ (A& x)
{
x.a ++;
x.b ++;
return x;
}
305 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
单目运算符的重载 2
operator ++ 作为成员函数的重载class A {
int a,b;
public:
A(int x, int y) : a(x), b(y) {}
A& operator ++ ( );//前++
};
A& A::operator ++ ( )
{
a++; b++;
return *this;
}
class A {int a,b;
public:A(int x, int y) : a(x), b(y) {}A& operator ++ ( );A operator++ (int );//后 ++
};A A::operator++(int dummy){
A temp = *this;a++; b++;return temp;
}
306 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
单加与单减的麻烦
Prefix 与 postfix?
++a .vs. a++
C++ 的处理前加为 operator++(a)
后加为 operator++(a,int)
使用一个 int 的哑元前 ++ 为左值,应该返回一个引用后 ++ 为右值,可以返回一个临时对象的值
307 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
双目运算符的重载 1
operator + 作为友员的重载class A {
int a,b;
public:
A(int x, int y) : a(x), b(y) {}
friend A operator + (const A&, const A&);
};
A operator + (const A& x, const A& y)
{
int a = x.a + y.a;
int b = x.b + y.b;
return A(a,b);
}
308 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
双目运算符的重载 2
operator + 作为成员函数的重载class A {
int a,b;
public:
A(int x, int y) : a(x), b(y) {}
A operator + (const A&);
};
A A::operator + (const A& x)
{
return A(a+x.a, b+x.b);
}
309 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
转换运算符
用于将一个对象转换成其他数据类型operator 类型名 ( );
转换运算符没有返回类型 类型名即返回类型
转换运算符的声明与定义class RMB {
int y;int j;int f;
public:operator double( ) {
return y + j/10.0 + f/100.0;}
};
310 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
流操作符 <<的重载
<< 作为友员函数的重载class A {
int a,b;
friend ostream& operator << (ostream&, const A&);
} ;
ostream& operator << (ostream& oo, const A&x)
{
oo << "(" << x.a << "," << x.b << ")";
return oo;
}
311 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
流操作符 >>的重载
>> 作为友员函数的重载class A {
int a,b;
friend istream& operator >> (istream&, A&);
} ;istream& operator >> (istream& ii, A&x)
{
char ch;
ii >> ch;
ii >> x.a;
ii >> ch;
ii >> x.b;
ii >> ch;
return ii;
}
312 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
可以重载哪些东西?
编译器为类自动生成的元素 Default constructor
Default destructor
Default copy constructor
Default operator=
所有的运算符不能重载的运算符: · , ·* , :: , ?: , sizeof, # , ##
无法自己定义新的运算符
313 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
重载的要点
Operator=只能当成员函数重载只能是成员函数 :
= , ( ) , [ ] , -> , ->* ,类型转换函数
推荐的原则所有一元运算符按成员函数来重载
建议以成员函数重载+= , -= , /= , *= , ^= , &= , |= , %= , >>= , <<=
其他二元运算符建议按友员重载
314 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
rmb.h 程序
#include <iostream>#include <ostream>#include <istream>using namespace std;class RMB{private: int y, j, f;public: RMB(int, int, int);
RMB(float); RMB(double);
RMB(const RMB&);RMB operator+ (const RMB&);
RMB operator- (const RMB&); RMB operator* (const int); RMB& operator= (const RMB&); operator float(); operator long(); friend ostream& operator<< (ostream&, const RMB&); friend istream& operator>> (istream&, RMB&); };
315 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
rmb.cc 程序
#include "rmb.h"RMB::RMB(int yuan, int jiao, int fen){
y = yuan;j = jiao;if(jiao >= 10){ y++;
j -= 10; }
f = fen; if(fen >= 10) { j++; fen -= 10;
}}RMB::RMB(float a){ y = (int)a; j = (int)((a - y) * 10); f = (int)((100*a) - (100*y) - (10*j)); }
316 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
rmb.cc 程序
RMB::RMB(double a){ y = (int) a; j = (int) ((a - y) * 10); f = (int) (100*a - 100*y - 10*j);}RMB::RMB(const RMB& r){ y = r.y; j = r.j; f = r.f;}RMB RMB::operator+ (const RMB& r){ int x = y + r.y; int y = j + r.j; int z = f + r.f; if(z >= 10) { y++; z -= 10; } return RMB(x, y, z);}
317 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
rmb.cc 程序
RMB RMB::operator- (const RMB& r){ return RMB(y - r.y, j - r.j, f - r.f);}RMB RMB::operator* (const int n){ float x = (float) *this; cout << "x=" << x << endl; x *= n; cout << "x=" << x << endl; RMB t(x); cout << "t=" << t << endl; return t;}RMB& RMB::operator= (const RMB& r){ if(this == &r) return *this; y = r.y; j = r.j;
318 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
rmb.cc 程序
f = r.f; return *this;}RMB::operator float(){ return (float) (y + j / 10.0 + f / 100.0); }RMB::operator long(){ return long(y * 100 + j * 10 + f); }ostream& operator<< (ostream& o, const RMB& r){ o << "Y" << r.y << "." << r.j << r.f << endl; return o;}istream& operator>> (istream& i, RMB& r){
float f; i >> f; r = RMB(f); return i;}
319 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
rmbmain.cc 程序
#include <iostream>using namespace std;#include "rmb.h"
int main(){ RMB r1(3.26f); RMB r2(2.16f); RMB r3 = r1 + r2; RMB r4 = r2 - r1; RMB r5 = r1 * 3; cout << "r1 = " << r1 << endl; cout << "r2 = " << r2 << endl; cout << "r1 + r2 = " << r3 << endl; cout << "r1 - r2 = " << r4 << endl; cout << "r5 = " << r5 << endl;}
320 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Exercises
设计一个字符串类 String ,要求该类能够完成以下操作(用函数重载完成)
要求:构造完整的类(构造、析构函数,拷贝构造函数,重载=操作符)
并且实现以下功能 String1=String2+String3 ( 重载+ )
String1 += String2 ( 重载+= )
(int)String1 ( 重载类型转换 int) ,将 String 对象中的所有字符的ASCII 相加后返回。
String1 == String2 ( 重载相等判断,两字符串相等返回真,不等返回假 )
cout << String1 (输出符号重载 )
cin >> String1 (输入符号重载 )
编写测试程序测试该类
321 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
322Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 9
323 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
I/O流
I/O 流
324 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
流的概念
Stream
325 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
流的特点
提供标准的 I/O 操作支持缓冲支持改向
326 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 中的 I/O 标准流
cin
cout
cerr
clog
iostream 类库 /usr/local/include/c++/3.2 [UNIX]
/usr/include/c++/3.2.2 [LINUX]
http://www.cplusplus.com/ref/iostream/
327 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 中 I/O 的结构
ios
istream ostream
fstream
iostreamifstream ofstream
328 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
标准 I/O流
cin
cout
cerr
clog
329 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
标准流程序 myIO.cc
#include <iostream>using namespace std;
int main( ){ char ch; cout << "Please enter some number." << endl; cin.get( ch ); cout << "ch=" << ch << "x" << endl; int i; float f; cin >> i >> f; cout << "i=" << i << endl; cout << "f=" << f << endl;}
330 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
cin流
A standard istream object
Buffered, standard input
Default is keyboard
331 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
istream流的操作
>> 操作get( )
getline( )
read( )
ignore( )
peek( )
putback( )
332 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
>>操作
>>的连续使用为什么可以连续使用 >>操作?
>>的返回值>>操作返回一个 istream 对象的引用
>>操作的重载功能
333 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
get( ) 操作
get( ) 操作 读取单个字符返回一个整数
字符的 ASCII 码? get 对回车换行的处理
get(char&) 操作 读取单个字符返回一个 istream 对象的引用
334 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
getline( ) 操作
读取一行遇到回车键
返回 istream 对象的引用getline() 操作与 >> 的区别 :
char string1 [256],
cin.getline(string1, 256); //get a whole line
cin >> string1; //stop at the 1st blank space
335 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
read( ) 操作
read(buf, len)
返回一个 istream 对象的引用多用于文件,对‘ \n’照读不误 :
ifstream is("edata.dat", ios::binary);
is.read( (char*) &Object, sizeof(Object));
336 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
ignore( ) 操作
ignore(len, delimiter)
忽略 len 个字符或者遇到‘ \n’ cin.ignore(255, ‘\n’); //clear out the buffer
337 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
peek( ) 与 putback( )
peek( ) 查看而不读取一个字符if (cin.peek() == ‘*’) …
Peek next character. Reads and returns the next character without extracting it from the stream.Returns EOF if stream is at the end of file and in any case where member good() (ios::good) would return false
Parameters. none
Return Value. The value of the next character in stream or EOF.
putback( ) 向输入流中插入一个字符串 (必须和 istream::get(char&) 一起使用 ,否则流将不能使用)if (ch == ‘* ’)
cin.putback(‘$’) ...Put the last character back to stream.
Decrements the next-character pointer for the input buffer if c was the last character got from the stream.
Parameters. c -- The character to put back. Must have the same value as the last character extracted.
Return Value. The function returns *this
338 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
ifstream
文件流输入 将一个文件打开,并按流的方式输入
初始化一个 ifstream 流对象ifstream fin("MyFile.txt");
文件流的操作>>操作fin.get( ch ) //char ch
fin.getline(buffer, MAX ) //char buffer[MAX]
…
339 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
文件输入的例子
ifstream myfin("myfile.txt");
char line[120];
int myInt = 0;
…
myfin.getline(line, 120);
myfin >> myInt;
…
myfin.close( );
340 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用 ifstream 的 fin.cc
#include <fstream>#include <iostream>using namespace std;int main(){ ifstream inf("test.txt"); char buf[200]; inf.getline(buf, 200); cout << "buf = " << buf << endl; int i; inf >> i; cout << "i = " << i << endl; char ch; ch = inf.get( ); cout << "ch = " << ch << endl; ch = inf.get( ); cout << "ch = " << ch << endl; inf.close( );}
341 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
使用 ifstream 的 fwc.cc
#include <iostream>using namespace std;#include <fstream>int main(int argc, char** argv){
ifstream fin( argv[1] ); char line[100]; int cnt = 0; do { cnt ++;
fin >> line;} while ( !fin.eof() );cout << "Total words : " << cnt-1 << endl;fin.close( );
}
342 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
cout流
A standard ostream object
Buffered, standard output
Default is screen
343 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
ostream 的操作
operator <<
put( )
write( )
width( )
fill( )
setf( )
344 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
<<操作
<<的连续使用为什么可以连续使用 <<操作?
<<的返回值<<操作返回一个 ostream 对象的引用
<<操作的重载功能
345 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
put( ) 操作
put( ) 操作输出单个字符返回一个 ostream 对象的引用 cout.put(‘H’).put(‘i’);
346 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
write( ) 操作
write(buf, len)
write( )返回一个 ostream 对象的引用 cout.write (buf, len) //char buf[len]
347 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
width( ) 操作
输出的默任宽度
cout.width(10);
cout << 123.4 << endl; //C:> 123.4
cout << 123 << endl;
348 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
fill( ) 操作
按width( ) 操作所定的宽度,对于指定用于填充空档位的字符
cout.width(10);
cout.fill(‘#’);
cout << 123.456 << endl; //C:>##########123.456
cout << 123 << endl;
349 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
setf( ) 操作
设输出标志操作
常见的输出控制标志 : cout.setf(ios::left) ios::left
ios::right
ios::dec
ios::oct
ios::hex
ios::showbase
ios::showpoint
ios::uppercase
ios::showpos
ios::scientific
350 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
格式化输出 1
特殊字符\n (new line)
\r (return)
\t
\\
\a (bell)
351 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
格式化输出 2
输出控制符flush: clear out buffer
endl: insert a ‘\n’, and clear out buffer
oct: set the output as oct.
dec
hex
352 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
ofstream
ofstream(fileName, mode)
ios::app : start writing at end of file
ios::ate: start reading or writing at end of file
Ios::in : open for reading
ios::trunc: truncate file to zero length if it exists
ios::nocreate : error when opening if file does not exist
ios::noreplace: error when opening for output if file exists.
ios::binary: open file in binary mode.
ios::out : open for writing
E.g. fstream file; file.open("Group.dat", ios::app | ios:: out |
ios::in | ios::binary);
353 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
文件输出的例子 fOut.cc
#include <fstream>#include<iostream>using namespace std;int main( ){
ofstream fout("test.txt");int k;char buf[50];fout << "This is a text file." << endl;cout << "Please enter a number:";cin >> k;fout << "The number you entered is " << k << endl;cout << "Please enter a word:";cin >> buf;fout << "The word you entered is: " << buf << endl;fout.close( );
}
354 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 ifof.cc
#include <iostream>using namespace std;#include <fstream>char convert(char c){ if ((c >= '0')&&(c <= '9'))
return '#'; if ((c >='A')&&(c <= 'Z')) { return c+32; } if ((c >= 'a')&&(c <= 'z')) {
return c - 32; } return c;}
355 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 ifof.cc
int main(int argc, char** argv){ ifstream fin( argv[1] ); ofstream fout( argv[2] ); for( ; ; ) { char ch = fin.get( ); if ( !fin.eof() ) fout << convert( ch ); else break;
}; fin.close( ); fout.close( );}
356 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
对对象的文件操作
将一个对象写入一个文件从文件中读入并恢复一个对象 :
357 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 obFile.cc
#include <fstream>#include <iostream>using namespace std;
class Animal{public:
Animal(int weight,long days):itsWeight(weight),DaysAlive(days){}~Animal(){}
int GetWeight()const { return itsWeight; }void SetWeight(int weight) { itsWeight = weight; }
long GetDaysAlive()const { return DaysAlive; }void SetDaysAlive(long days) { DaysAlive = days; }
private:int itsWeight;long DaysAlive;
};
358 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 obFile.cc
int main(int argc, char *argv[]) // returns 1 on error{
if (argc != 2){
cout << "Usage: " << argv[0] << " <filename>" << endl;return(1);
}ofstream fout(argv[1],ios::binary);if (!fout){
cout << "Unable to open " << argv[1] << " for writing.\n";return(1);
}Animal Bear(50,100);
fout.write((char*) &Bear,sizeof Bear);
fout.close();
359 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 obFile.cc
ifstream fin(argv[1],ios::binary);if (!fin){
cout << "Unable to open " << argv[1] << " for reading.\n";return(1);
}Animal BearTwo(1,1);cout << "BearTwo weight: " << BearTwo.GetWeight() << endl;cout << "BearTwo days: " << BearTwo.GetDaysAlive() << endl;fin.read((char*) &BearTwo, sizeof BearTwo);cout << "BearTwo weight: " << BearTwo.GetWeight() << endl;cout << "BearTwo days: " << BearTwo.GetDaysAlive() << endl;fin.close();return 0;
}
360 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Reference URL
http://www.cppreference.com
This URL contains a lot of functions reference pages, such as standard C Library, iostream library and STL library.
361 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Exercises
定义一个 Dog类 , 包含体重和年龄两个数据成员及相应的成员函数。声明一个实例 dog1,体重为 5,年龄为 10, 使用I/O 流把 dog1 的状态写入磁盘文件(文件名称从键盘输入获得) : 再声明另一个实例 dog2,通过读文件把 dog1 的状态赋给 dog2
从键盘读入字符串 , 并将它们写入磁盘(以追加方式 ios::app )。当用户输入‘~’字符时 ,程序停止。
362 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
363Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 10
364 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Exception
异常,意外,出错程序常见问题介绍
错误的类型人为的客观的
错误的处理方法传统的 异常方式
365 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
bulletproof
BugsProgrammer made mistake
Logic errorProgrammer misunderstand the problem or solution
ExceptionUnusual but predictable.
366 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
异常
异常的特点客观存在,不能消灭但能够预测并有选择性的去处理 You can prepare for them.
367 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
典型的异常
你知道计算机可能会耗光内存当没有更多内存空间时,你:
死机通知用户并退出程序通知用户并让用户来处理采取适当的纠正行动,让用户不受干扰
368 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
C++ 提供的异常处理机制
Exception 是一个对象出现意外的地方将会产生一个异常:抛出一个异常对象 该对象被传递到负责意外处理的地方由负责意外处理的代码专门进行统一的异常处理异常对象包含有意外发生的详细信息
369 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
常见的异常
常见的异常比如:内存请求失败文件操作不成功
异常的发生都在程序的较底层异常的表现都在较高层,对异常的处理逻辑也都在较高层面,特别是直接与用户打交道的代码。异常提供了一个快速的通道,把异常信息从其发生的地方直接传递到对意外进行处理的地方
370 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
异常的产生
任何时候,程序在执行中遇到了非正常状况都可以抛出异常异常用 throw 语句抛出
A *p = new A( );
if (p == NULL) {
throw "Out of Memory.";
}
一旦抛出异常,则程序将在 throw 语句处跳出
371 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
异常的捕捉
异常也由程序员负责捕获用 try{…}catch( ){…} 语句来捕获异常没有捕获的异常将被忽略
try {
}catch(OutOfMemory) {
…
}catch(FileNotFound) {
…
}
372 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
异常的传递
产生异常之后,程序会立刻跳转跳出到最近的一层捕获异常的语句如果当前没有捕获语句或者捕获语句中没有匹配的异常,则程序会跳出当前的函数
在函数的调用处,如果没有捕获住异常,则直接跳转到更高一层的调用者如果一直没有捕获该异常,C ++将会使用默认的异常处理函数
该处理函数可能会让程序最终跳出main 函数并导致程序异常终止
373 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
抛异常的例子
#include <iostream>
using namespace std;
int main( )
{
int a, b;
a = 8;
b = 4;
double c = a/b;
cout << c << endl;
}
a = 8;b = 0;
c = a/b;
…
if (b == 0)throw "Divided by Zero!";
else {double c = a/b;cout << c << endl;
}
374 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
捕获异常
#include <iostream>using namespace std;int main( ){
int a, b;a = 8;b = 4;
try{if (b == 0)
throw "Divided by Zero!";else {
double c = a/b;cout << c << endl;
} }catch(…) {
cout << "Exception caught!" << endl; }}
375 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
异常传递的例子
#include <iostream>using namespace std;void f1( ){
…throw "A exception.";…
}void f2( ){
f1( );}int main(){
…f2();…
}
376 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
多层异常的捕获
try {
}catch(OutOfMemory) {
…
}catch(FileNotFound) {
…
}catch(…) {
…
}
377 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
捕捉异常的形参与值
多重 catch 语句异常匹配的顺序异常对象的添值
378 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
异常的类型
异常就是一个对象异常也会有类型
379 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
自定义异常
用户自定义的异常
380 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
自定义异常的例子
自己定义 OutOfRang 类并抛出一个 OutOfRang 对象作为异常
381 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 array.cc
…………….
int& MyArray::operator[ ] (int idx)
{
if ((idx >= max)||(idx < 0))
{ //throw "OutOfRange";
throw new OutOfRange(max, idx);
}else
return pV[idx];
}
………………..
382 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Inner class
定义在一个类里面的类异常类常封装为 inner class
383 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Inner class example excpt.cc
#include <iostream>using namespace std;class MyClass { int score; public: class innerE { int val; char msg[100];
public: innerE(char* s, int v=0){ strcpy(msg, s);val=v;}
void disp( ) { cout << msg <<": "<<val<< endl; } }; MyClass(int s=0):score(s) {if(s<0||s>100) score=0; } void disp( ) { cout << score << endl; } void set( int s ){ if(s<0||s>100)throw innerE("not a proper score",s); score = s; }};
384 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Inner class example excpt.cc
int main( ){ MyClass mc; try { mc.disp(); mc.set(120); mc.disp(); } catch(MyClass::innerE e) {
e.disp( ) ; }}
385 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Exercises
定义一个 myArray 的类,要求重载 operator[] 用于检查给进来的参数是不是超过数组的界限,如果是的话,抛出一个异常 , 否则返回相应的值的引用。
operator[] 重载的原型• int& operator[ ] (int index) { …. …. }
编写一个程序测试异常。
提示:异常可以写成 inner class ,也可以写成 outer class 。
386 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
387Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 11
388 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
重要数据结构
链表 : 它由设计为大小合适的小的容器组成, 这些容器可根据需要链接在一起。链表组件:链表由节点组成。每个节点内可放置指定的数据类型。
头节点: 其工作是管理链表的头。尾节点: 初始时,头节点的 myNext 指针指向尾节点。内部节点:存放数据类型。
myHead myNext
链表 头节点 尾节点
389 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
链表的特点
非常重要的数据结构 在计算机系统中有广泛的应用
灵活比数组节省空间访问比较慢操作比较复杂
390 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
链表
使用结构与指针可以实现链表一个典型的链表
节点
链表头
header
391 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
链表
Flexible space use
Dynamically allocate space for each element as needed
Include a pointer to the next item
Linked list
Each node of the list contains
the data item (an object pointer in our ADT)
a pointer to the next node
Data Next
object
392 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
链表
Collection structure has a pointer to the list head
Initially NULL
Collection
Head
393 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
链表
Collection structure has a pointer to the list head
Initially NULL
Add first item
Allocate space for node
Set its data (may be pointer to object)
Set Next to NULL
Set Head to point to new node
Head
Collection
node
Data Next
object
394 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
链表
Add second item
Allocate space for node
Set its data pointer to object
Set Next to current Head
Set Head to point to new node
Data Next
object
node
Data Next
object2
nodeHead
Collection
395 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
链表通常的节点类型
构成链表显然离不开指针链表的定义
struct Person {
char name[20];
unsigned int age;
char address[100];
Person *next;
};
396 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
链表的操作 1
取头取尾取下一个节点增加一个节点插入一个节点删除一个节点查找某一个节点
397 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
链表的操作 2
链表的建立链表的删除
398 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
基本链表的操作与实现
插入节点 (high efficient)删除节点 (same as search in O(N)). No need to fill "holes"like
array deletion.建立与删除链表查找一个节点 (O(N))更新一个节点
In general, a linked list has almost the same efficiency as a
non-ordered array for above operations.
399 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
一个整数型的链表的例子
节点struct Node{
int v;
Node *next;
};
操作Insert
Delete
400 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
实现该链表 linklist.cc
#include <iostream>
using namespace std;
struct Node
{
int V;
Node *next;
};
Node *header = NULL;
void Insert(Node *pNode)
{
pNode->next = header;
header = pNode;
}
void Delete(Node *pNode)
{
if ((pNode == NULL)||(header == NULL))
return;
if (pNode == header)
{
header = header->next;
delete pNode;
return;
}
Node *prev = header;
while (prev->next != pNode)
if (prev->next == NULL)break;
else prev = prev->next;
401 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
实现该链表 linklist.cc
if (prev->next != NULL) { prev->next = pNode->next; delete pNode; }}int main( ){
cout << "Please enter 10 numbers:" << endl;for(int i=0; i<10; i++)
{int num;cin >> num;Node* ptr = new Node;ptr->V = num;
ptr->next=NULL;
Insert(ptr);
}
402 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
实现该链表 linklist.cc
Node *ptr = header;
while(ptr != NULL)
{
cout << ptr->V << ", ";
ptr = ptr->next;
}
cout << endl;
//ptr = header;
while(header)//while(ptr != NULL)
{
Delete(header);//Delete(ptr);
//ptr = header;
}
} //end linklist.cc
403 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Another example linklist2.cc
#include <iostream>using namespace std;class CLink{ class Node {
char ch;Node *next;
public:Node(char c)
{ ch = c;
next = NULL;}Node* GetNext( ) { return next; }
void SetNext(Node *ptr) { next = ptr; }char GetChar( ) { return ch; }
};Node* head;Node* cur;
public: CLink( ) { head = cur = NULL; }
404 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Another example linklist2.cc
char GetHead( ) { cur = head; if (head != NULL) { return head->GetChar(); }else { return '\0'; } } char GetNext( ) {
if (cur == NULL) return '\0';
cur = cur->GetNext();return (cur != NULL)? cur->GetChar( ):'\0';
}void AddNode(char c)
{Node* p = new Node(c);p->SetNext(head);head = p;
}
405 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Another example linklist2.cc
~CLink( ) {
Node *p; while(head != NULL) {
p = head->GetNext( );delete head;head = p;
} }};int main( ){
cout << "Please enter a string:" << endl; char ch;
CLink mylink;
while((ch=cin.get()) != '\n') { mylink.AddNode(ch); } cout << mylink.GetHead(); while((ch=mylink.GetNext()) != '\0') { cout << ch; } cout << endl;}
406 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
变化了的链表
双向链表struct Node{
int v;
Node *prev;
Node *next;
};head
tail
prev prev prev
407 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
变化了的链表
Class Dlinklist{ Node * head; Node * tail; public: Dlinklist() { head = NULL; tail = NULL; } void insertFirst(int d); void insertLast(int d); void deleteFirst(); bool isEmpty(); void display(); }……………..You will be asked to implement above functions in your assignment.
408 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
409Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 12
410 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
栈
栈介绍
push pop
411 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
堆栈的特点
先进后出,后进先出在一个线性的存储空间中如何实现这种特殊的 LIFO 操作?
412 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
栈的操作
将一个元素压入栈中 push( )
从栈中取出一个元素 pop( )
判断栈有没有元素 empty( )
问栈中还有几个元素 count( )
将栈中的所有元素清空 clear( )
初始化一个栈 reset( )
413 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
栈的应用
栈在函数调用中的作用栈被广泛的应用在编译器中
414 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
栈的实现
栈的基本原理是一致的栈的具体实现是多种多样的典型的栈的实现
用数组来实现一个栈 用链表来实现一个栈
415 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
用数组实现一个字符栈 cstack.cc
#include <iostream>using namespace std;
class cstack { char v[200]; int cur;public: cstack( ); int push(char); char pop( ); bool isempty( ); void reset( );};
416 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
用数组实现一个字符栈 cstack.cc
cstack::cstack( ){ cur = 0; }int cstack::push(char i){ v[cur++] = i; return cur;}char cstack::pop( ){ return v[--cur]; }
bool cstack::isempty( ){ if (cur > 0) return false; else
return true;}void cstack::reset( ) { cur = 0; }
417 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
用数组实现一个字符栈 cstack.cc
int main( )
{
cstack stk;
cout << "Please enter a string:" << endl;
char ch;
do {
ch = cin.get( );
stk.push( ch );
} while (ch != '\n');
while ( !stk.isempty() )
cout << stk.pop();
cout << endl;
}
418 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
用链表实现一个字符栈
This is your assignment.
419 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Queue
FIFO: First in, First out.
top tail
pop( ) insert( )
420 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
封装一个 Queue: myqueue.cc
#include <iostream>
using namespace std;
struct node
{
int data;
node* next;
node(int n, node* p=NULL) : data(n), next(p) { }
node() : next(NULL) { }
};
421 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
封装一个 Queue: myqueue.cc
class Queue { private: node* top; node* tail; public: Queue() { top = NULL; tail = NULL; } ~Queue(); void insert(int); int pop(); bool empty( ) { return top == NULL;}};
422 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
封装一个 Queue: myqueue.cc
void Queue::insert(int n) // insert new node at tail of list
{ node* temp = new node(n, NULL);
if (tail == NULL)
tail = top = temp;
else
{
tail -> next = temp; // insert after existing tail node
tail = temp;
}
}
423 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
封装一个 Queue: myqueue.cc
int Queue::pop()
{ node* fetch = top; // copy of top
if (fetch != NULL)
{ top = fetch -> next;
int x = fetch -> data;
delete fetch;
return x;
}
else
{ cout << "ERROR: Queue EMPTY!\n";
return 0;
}
}
424 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
封装一个 Queue: myqueue.cc
Queue::~Queue()
{ int count = 0;
while (top != NULL)
{
node* dead = top;
top = top -> next;
delete dead;
count++;
}
cout << "Queue destroyed, " << count << " nodes deleted\n";
}
425 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
封装一个 Queue: myqueue.cc
int main ()
{
Queue q;
q.insert(2);
q.insert(4);
q.insert(6);
q.insert(8);
while ( ! q.empty() )
cout << q.pop() << endl;
cout << "That\'s all the queue\n";
return 0;
}
426 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
用 stack 封装成一个 Queue
This is your assignment …
427 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Binary Trees
Why use binary trees?
It combines the advantage of two other structures: an sorted array and a linked list.
Quick search, insert, and delete items.
428 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Binary Trees
What is a tree?
A tree consists of nodes connected by edges.
A tree example:
nodes
edges
429 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Binary Trees
What is a binary tree?
Every node in a tree can have at most two children.
What is a binary search tree?
A node’s left child must have a key less than its parent.
A node’s right child must have a key greater than or equal to its parent.
430 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Binary Search Trees
53
30
47
39
9
14
3423
72
61 84
79
431 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Binary Search Trees
BinaryTree. h
#include <iostream> using namespace std;
class BinaryNode{ int iData; BinaryNode* left; BinaryNode* right;
public: BinaryNode( const int theData, BinaryNode *lt=NULL, BinaryNode *rt=NULL ) : iData( theData), left( lt ), right( rt ) { } friend class BinarySearchTree; };
432 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Binary Search Trees
class BinarySearchTree{ private: BinaryNode* root; void add(const int x, BinaryNode* t); void makeEmpty(BinaryNode* t) const; void printTree( BinaryNode* t ) const;
public: BinarySearchTree( ) { root = NULL; }
BinarySearchTree( const BinarySearchTree & rhs );
~BinarySearchTree( );
433 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Binary Search Trees
BinaryNode* getRoot() const { return root; } BinaryNode* find( const int key) const; void insert( const int x ); void printTree( ) const; void preOrder(BinaryNode* t); void inOrder(BinaryNode* t); void postOrder(BinaryNode* t); };
434 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Binary Trees
Show the procedure to find a node:
Show the procedure to insert a node:
Traversing a binary search tree:
Inorder traversal: A + B * C
Preorder traversal: *A + BC
Postorder traversal: ABC * +
+
*
B C
A
435 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
436Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 13
437 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
什么是算法
算法是在有限步骤内求解某一问题所使用的一组定义明确的规则。
通俗点说,就是计算机解题的过程。在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法。前者是推理实现的算法,后者是操作实现的算法。
438 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
什么是算法
一个算法应该具有以下五个重要的特征:
有穷性: 一个算法必须保证执行有限步之后结束;
确切性: 算法的每一步骤必须有确切的定义;
输入: 一个算法有 0 个或多个输入,以刻画运算对象的初始情况,所谓 0 个输入是指算法本身定义了初始条件;
输出: 一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的;
可行性: 算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成。
439 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
什么是算法
算法的复杂性 (the time complexity) 是算法效率的度量,是评价算法优劣的重要依据。
一个算法的复杂性的高低体现在运行该算法所需要的计算机资源的多少上面,所需的资源越多,我们就说该算法的复杂性越高;反之,所需的资源越少,则该算法的复杂性越低。
440 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
算法分析基础
简化的计算模型算法分析的表示方法 : Most of the algorithms apply directly to specific data structures.
Insert a new data item.
Search/delete for a specified item.
Iterate/sort all the items in a data structure.
重要的算法介绍• 查找与排序
441 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
算法分析
分析什么
•确定与检验程序正确与否•运行速度•程序的复杂性•程序的可靠性•使用内存的大小•代码的 size
对于任意给定的问题,设计出复杂性尽可能低的算法是我们在设计算法时追求的一个重要目标;另一方面,当给定的问题已有多种算法时,选择其中复杂性最低者,是我们在选用算法适应遵循的一个重要准则。
442 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序的性能
hardware
The programming language used
The compiler used
The OS
443 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
计算模型
存取操作赋值操作函数调用函数返回
444 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
运行效率
平均运行时间最佳与最差的运行情况Big O Notation: in computer science, it’s useful to have a
shorthand way to say how efficient a computer algorithm is.
A linear search: O(N)
A binary search: O(logN)
445 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Big O Notation
N (items)
Nu
mb
er o
f st
eps
O(N )2
O(N)
O(logN)
446 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
算法分析的表示法
大 O 表示方法:渐进上界法• 渐进原理
• 一种算法所花的时间肯定比某种已知的少
大表示方法:渐进下界法
447 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
算法设计策略
常用的算法设计策略有:
蛮力法 ---- 穷举所有可能性。
递归技术 —— 最常用的算法设计思想,体现于许多优秀算法之中。
分治法 —— 分而制之的算法思想,体现了一分为二的哲学思想。
模拟法 —— 用计算机模拟实际场景,经常用于与概率有关的问题。
贪心算法 —— 采用贪心策略的算法设计。
优化法 ----- 利用生物学优选原理。
448 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
排序
常用的重要排序方法• 选择排序法 : O(N2 )
• 冒泡排序法 : O(N2 )
• 插入排序法 : O(N2 )
• 快速排序法 : O( N * logN )
449 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
选择排序
最直接的排序方法每次选择一个最大(最小)的元素放到应该的位置
450 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
冒泡排序法
多轮排序每轮都要比较所有相邻的数据对将数据对按单一方向交换(由升序与降序决定交换方向)直到最后,所有的数据都已经排好了顺序见 p-134 的冒泡排序
451 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
插入排序法
将头两个元素排序接下来依次将每一个元素排到正确的位置直到所有的元素都排完
452 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
快速排序法 1
效率最高的排序方法选出一个分界值,把数组分成两个部分大于等于分界值的元素集中到数组的某一部分,小于分界值的元素集中到另一部分对于分成的两个部分分别再做同样的操作
453 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
快速排序法 2
• 对于如下 13 个元素 V[]
9 8 7 5 4 3 1 2 6 0 11 9 1
• 选最左边的元素值为 pivot
• 下标 l从左往右如果 V[l]>pivot ,则停止
• 下标 r从右往左如果 V[r]<=pivot ,则停止
• 将 V[l] 与 V[r] 的值交换• 继续,直到 l>=r
• 将 pivot 与 V[r]交换• 对于两个集合 (left, r-1) 与 (r+1, right)递归
454 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
高级算法
Optimization algorithms:
• Genetic algorithm:
A genetic algorithm (GA) is an algorithm used to find approximate solutions to difficult-to-solve problems,
inspired by and named after biological processes of inheritance, mutation, natural selection, and the genetic crossover that occurs when parents mate to produce offspring.
455 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
高级算法
Neural Network:
An artificial neural network, more commonly known as a neural
network, is a mathematical model for information processing based
on a connectionist approach to computation. The original inspiration
for the technique was from examination of bioelectrical networks in
the brain formed by neurons and their synapses. In a neural network
model, simple nodes (or "units", "neurons") are connected together
to form a network of nodes - hence the term "neural network".
456 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
NP and NP-hard problems
• A problem is assigned to the NP (nondeterministic polynomial time) class if it is verifiable in polynomial time by a nondeterministic Turing machine.
• A problem is NP-hard if an algorithm for solving it can be translated into one for solving any other NP-problem . Examples of NP-hard problems include the Hamiltonian cycle and traveling salesman problems.
457 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
458Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Chapter 14
459 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
STL 与自定义模板
STL
自定义模板
460 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
模板
模板简介模板的特点
A "parameterized types"
STL was adopted into the definition of C++
给予编译器学习的能力,教会它产生新的类型
461 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
模板与实例化
模板是对所有类型所下的一种定义使用时必须要对它实例化
462 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
自定义函数模板,类模板的格式
函数模板: template < 类型形参 > 返回类型 FunctionName ( 形参 )
{
//…….
}
类模板: template < 类型形参 > class className
{
//…..
};
template < 类型形参 >
返回类型 className < 类型名表 > ::MemberFunction1( 形参 )
{ //….. }
463 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
简单的函数模板
template <class T>
T Max(T a, T b)
{
return (a>b ? a : b);
}
int main( )
{
cout << "max(5, 2)=" << Max(5, 2) << endl;
cout << "max(a, b)=" << Max(‘a’, ‘b’) << endl;
}
464 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
函数模板的重载
template <class T>
T Min(T a, T b)
{
return (a>b ? b : a);
}
char * Min(char* a, char* b)
{
return (strcmp(a,b)>0 ? b : a);
}
int main( )
{
cout << "min(5, 2)=" << Min(5, 2) << endl;
cout << "min(a, b)=" << Min("abc", "xyz") << endl;
}
465 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
完整的 Array 类模板与 Disp 函数模板 1
#include <iostream>using namespace std;const int DefaultSize = 10;template <class T> class Array {public:
Array(int itsSize = DefaultSize);Array(const Array &rhs);~Array() { delete [] pType; }Array& operator=(const Array&);T& operator[](int index) { return pType[index]; }int getSize() { return itsSize; }
private:T *pType;int itsSize;
};
466 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
完整的 Array 类模板与 Disp 函数模板 2
template <class T>Array<T>::Array(int size):itsSize(size){
pType = new T[size];for (int i = 0; i<size; i++)
pType[i] = 0;}template <class T>Array<T>::Array(const Array &rhs){
itsSize = rhs.GetSize();pType = new T[itsSize];for (int i = 0; i<itsSize; i++)
pType[i] = rhs[i];}
467 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
完整的 Array 类模板与 Disp 函数模板 3
template <class T>
Array<T>& Array<T>::operator=(const Array &rhs)
{
if (this == &rhs)
return *this;
delete [] pType;
itsSize = rhs.GetSize();
pType = new T[itsSize];
for (int i = 0; i<itsSize; i++)
pType[i] = rhs[i];
return *this;
}
468 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
完整的 Array 类模板与 Disp 函数模板 4
template <class T>
void Disp( Array<T>& theArray)
{
for(int j=0; j<theArray.getSize(); j++) {
cout << theArray[j];
}
}
469 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
完整的 Array 类模板与 Disp 函数模板 5
int main( )
{
Array<int> theArray;
Array<char> theString;
for (int i = 0; i < theArray.getSize(); i++) {
theArray[i] = i*2;
theString[i] = 'A' + i;
}
Disp( theArray );
cout << endl;
Disp( theString );
}
470 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
STL 简介
STL被接纳为 C++ 的一部分 作为编译器的一部分
什么是 STL
Template based container classes
Sequence, associative, etc
Some common algorithm
Sorting, searching
Tested, debugged, high performance and free
Reusable
STL components:
Containers
Algorithms
Iterators
471 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Containers
容器的特点包含其他对象的对象
存储方式 直接存储
容器中有一份对象的拷贝占空间,一个对象不能放入多个容器,不能包含本身
间接存储容器只保存对象的指针 对对象的存取通过引用一个指针
472 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Sequence Containers
vector
类似于数组,但更安全 能自动增长
list
对于频繁的插入与删除做了优化
deque vector 的子类, 但可从头,尾两端操作。
473 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
vector
一个同类元素的有序序列类似于数组,但更强大,更安全
template <class T, class A = allocator<T>> class vector
{
…
};
vector 中的元素能够自动增长vector 的使用
#include <vector>
vector< int > vInts;
vector< float > vFloats;
vector< Student > softClass(50);
474 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
vector 的操作
[ ] //按下标取元素front() //取第一个元素back() //取最后一个元素at() //比较安全的 [] ,能抛出 out_of_range 异常insert() // 在给定的位置插入一个或多个元素pop_back() //删除最后一个元素erase() //删除一个或多个元素
475 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
能放在 vector 中的对象
要支持默认的构造函数无参数的构造函数
支持拷贝构造函数支持重载赋值操作vector适合按下标存取元素的需求
476 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
vector 的使用
#include <vector>
…
vector<int> iV(10);
for(int i=0; i<10; i++)
iV[i] = 2*i;
vector<int>::iterator ci = iV.begin();
ci += 2;
iV.insert( ci , 888);
for(ci=iV.begin( ); ci!=iV.end( ); ci++)
cout << *ci << endl;
477 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
list
与 vector 类似,也是一个有序的列表对插入与删除操作进行了优化对元素的访问可通过 iterator来进行
list<int> iList;
list<int>::const_iterator ci = iList.begin();
cout << *(++ci);
478 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
list 的操作
push_front() // 在列表头部增加元素pop_front() // 在列表头部删除元素push_back() // 在列表尾部增加元素pop_back() // 在列表尾部删除元素list 可以双向增长list适合对元素频繁的插入与删除的应用
479 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
list 的使用
#include <list>
…
list<int> iL;
list<int>::iterator ip = iL.begin();
for(i=0; i<10; i++, ip++)
iL.insert( ip, i*10); //is this in order?
iL.sort( );
ip = iL.begin();
while( ip != iL.end() ) {
cout << *ip << ":";
ip ++;
}
480 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 lstack.cc
#include <list>#include <iostream>using namespace std;class lstack {
list<char> vc;list<char>::iterator v;
public: lstack(); lstack(char); char push(char); char pop(); void disp();};lstack::lstack(){ }
lstack::lstack(char a){ v = vc.begin(); vc.insert(v, a);}
481 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 lstack.cc
char lstack::push(char a){
v = vc.begin();vc.insert(v, a);
}char lstack::pop(){ char b; if(!vc.empty()) { v = vc.begin(); b = *v; vc.pop_front(); } return b;}void lstack::disp(){ for(v = vc.begin(); v != vc.end(); v++)
cout << *v << endl;}
482 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
程序 lstack.cc
int main()
{
lstack ls;
cout << "The push is: " << endl;
for(int i = 0; i < 5; i++)
ls.push('a' + i);
ls.disp();
cout << "The pop is: " << endl;
for(int i = 0; i < 5; i++)
ls.pop();
ls.disp();
}
483 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Special Containers
Container Adapters: adapt to STL standard containers.
Stack
Queue
Priority queues
484 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Stack adapter example stackSTL.cc
#include <iostream>#include <stack>using namespace std;int main(){ stack <int> st; st.push(1); st.push(2); st.push(3); cout << st.top() << ‘ ‘ ; st.pop(); st.top() = 77; st.push(4);
485 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Stack adapter example stackSTL.cc
while(!st.empty())
{
cout << st.top() << ‘ ‘;
st.pop();
}
cout << endl;
}
486 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Queues adapter queueSTL.cc
#include <iostream>#include <queue>#include <string>using namespace std;int main(){ queue<string> q; q.push("Hello"); q.push("world"); cout << q.front(); q.pop(); cout <<q.front(); q.push("!"); cout <<q.back(); q.pop(); cout << " number of elements in the queue: " << q.size(); cout << endl;}
487 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Associative Containers
vector,list 的特点 有序的元素集合按顺序或者按下标存取无法按关键字存取
Associative containers 的特点 map
multimap
set
multiset
488 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
map
可按关键值实现快速存取的容器每个元素是一个 <key, value> 对key必须是唯一的
489 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
map 的使用
Map 可按照 key去取值map<string, Student> softClass;
Student Jack("Jack", 20);
softClass["Jack"] = Jack;
Student Lisa = softClass["Lisa"];
也可使用 iterator 操作map< string, Student >::const_iterator ci = softClass.begin();
cout << ci->first; //print Key value
cout << ci->second; //print Student object
490 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
map 的例子
#include <map>
…
map<char*, int > iM;
iM.insert(map<char*, int >::value_type("ABC", 100));
iM.insert(map<char*, int >::value_type("XYZ", 200));
map<char*, int >::const_iterator mp = iM.begin();
while( mp != iM.end() ) {
cout << mp->first << " : " << mp->second << endl;
mp ++;
}
int ia = iM["ABC"];
int ib = iM["XYZ"];
491 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
multimap
类似于 map
但关键值可以不唯一,多个元素可有相同的关键值
492 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
multimap 的例子
#include <map>
…
multimap<char*, int > iM;
iM.insert(multimap<char*, int >::value_type("CXP", 100));
iM.insert(multimap<char*, int >::value_type("CXP", 200));
multimap<char*, int >::const_iterator mp1;
multimap<char*, int >::const_iterator mp2;
mp1 = iM.upper_bound("CXP");
mp2 = iM.lower_bound("CXP");
multimap<char*, int >::const_iterator mp;
for(mp = mp2; mp!=mp1; mp++)
cout << mp->first << " : " << mp->second << endl;
493 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
set
与map 相似但元素不是 <key, value> 对一个元素就是一个唯一的 key
即使插入重复的值, set 将只保存一份
494 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
set 的例子
#include <set>
…
set<int> iS;
iS.insert(1);
iS.insert(2);
iS.insert(3);
iS.insert(5);
iS.insert(3);
set<int>::const_iterator sp = iS.begin();
for(; sp!=iS.end(); sp++)
cout << *sp << endl;
495 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
multiset
与 set 类似但容许重复的值
496 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
multiset 的例子
#include <set>
…
multiset<int> iMS;
iMS.insert(1);
iMS.insert(2);
iMS.insert(3);
iMS.insert(5);
iMS.insert(3);
multiset<int>::const_iterator msp = iMS.begin();
for(; msp!=iMS.end(); msp++)
cout << *msp << endl;
497 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
相关的信息
查看类模板的头文件 /usr/local/include/c++/3.2/
498 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
STL Algorithms
STL provides some standard algorithms:
Search : for_each(), find(), find_first_of(), find_end()…
Sort: sort(), reverse() …
Copy: copy(), copy_backward()…
Modify: replace(), merge(), remove()…
Numeric: min(), max(), count(), swap(), accumulate()…
……
Algorithms usually work with STL Iterators together.
499 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
STL Algorithms examples myFind.cc
#include <iostream>
#include <algorithm>
using namespace std;
int arr[ ] = {11, 22, 33, 44, 55, 66, 77, 88};
int main()
{
int* ptr;
ptr = find(arr, arr+8, 33);
cout << "First object with value 33 at offset: " << (ptr-arr)
<< endl;
}
500 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
STL Algorithms examples myCount.cc
#include <iostream>
#include <algorithm>
using namespace std;
int arr [ ] = {33, 22, 33, 44, 33, 55, 66,77};
int main()
{
int n = count(arr, arr+8, 33);
cout << " there are " << n << " 33’s in arr. " << endl;
}
501 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
STL Algorithms examples patternSTL.cc
#include <iostream>
#include <algorithm>
using namespace std;
int source[ ] = { 11, 44, 33, 11, 22, 33 ,11, 22, 44};
int pattern[ ] = { 11, 22, 33};
int main()
{
int* ptr;
ptr = search(source, source+9, pattern, pattern+3);
if(ptr == source+9)
cout << " No match found\n";
else
cout << "Match at " << (ptr – source) << endl;
}
502 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
STL Algorithms examples: in_to_cm.cc
#include <iostream>
#include <algorithm>
using namespace std;
void in_to_cm(double);
int main()
{
double inches[ ] = {3.5, 6.2, 1.0, 12.75, 4.33};
for_each(inches, inches+5, in_to_cm);
cout << endl;
}
void in_to_cm(double in)
{
cout << (in * 2.54) << " ";
}
503 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A
504Copyright Tarena Corporation, 2005. All rights reserved.
Tarena High-End IT Training
www.tarena.com.cn
加拿大达内科技 ( 中国 ) 公司
中国北京 电话:( 010 ) 62136369 、 62132839 地址:北京市海淀区北三环西路甲 18 号 (大钟寺附近)中鼎大厦 B 座 7 层
中国上海 电话:( 021 ) 61202630 、 61202603 地址:上海市北京东路 668 号 上海科技京城 C 区 9 层
加拿大多伦多 电话:( 416 ) 491-6456 地址: Suite 1208, Deerford Road, Toronto, Ontario, Canada 邮编: M2J 3J3 邮件: [email protected] 网址: www.tarena.ca
中国广州 电话:( 020 ) 85518868 、 85518898 地址:广州天河区岗顶侨鑫教育主楼三层
The C++ Programming Language
Core C++ Test
505 外企的师资、外企的技术、外企的品质外企的师资、外企的技术、外企的品质北京:北京: 010-62196102 010-62196102 上海上海 :021-61202630 :021-61202630 广州:广州: 020-85518868020-85518868
Q & A