《第一章》
数据类型分为三种:
-简单数据类型
-用户定义数据类型
-抽象数据类型:在定义数据的同时,必须定义对数据的操作;它的数据成分是不可见的,也不可以直接操作。对象和抽象类型的关系,类似于 整型变量和整型数据类型的关系。
数据封装将一组数据和这组数据相关的操作集合封装在一起,形成了一个能动的实体,成为对象。用户不必知道对象行为的实现细节,只需根据对象提供的外部特性接口访问对象。
在C++中,实现数据封装的机制是“类(class)”。
在Java和C#中,实现数据封装的机制也是“类(class)”。
《第二章》——C++语法
一个标识符,一旦被定义在一个名字空间里,那么它就被隐藏在了那个名字空间里。 也就是说,该标识符只能被包含在那个名字空间里的语句直接访问。 试图在名字空间之外访问该标识符会得到一个编译器找不到标识符的错误。
C++提供new和delete来动态分配存储空间。动态分配管理的方法要求delete的操作数必须是一个new返回的指针,对不是由new得到的任何其他地址类型,使用delete将导致严重错误。 这种错误是运行时的错误,很难调试,因此使用delete时请务必注意。 回收new分配的数组空间,使用delete进行delete [] p;表明一个由 p 指向的数组空间被回收了。
1 动态分配和释放单个数据的存储区语法为:
type * p;
p=new type;
…//通过*p方式访问new申请的空间。
delete p;
2 用new运算符初始化单个数据的存储区
语法为:
type * p;
p=new type(…);
…
delete p;
(1)一维数组 语法为:
type * p;
p=new type[s];
… //通过p[i]的方式访问数组元素。
delete [] p;
(2)n维数组语法为
type (* p)[常量1][常量2]…[常量n-1];
p=new type[s][常量1][常量2]…[常量n-1];
…//通过p[i1][i2]…[in]的方式访问数组元素。
delete [] p;
s指定数组中的第一维元素个数,可以是常量或表达式。
不能省略 。
函数
内联函数
宏替换的好处是没有系统的调用开销。函数正相反。为结合两者的优点,C++语言允许定义内联函数。在函数原型前冠以“inline”表示一个内联函数。例如:
inline void function(int a, int b);
编译时,在调用 function的地方用函数体替换,能够加快代码执行,减少调用开销。
函数重载
由于所有C++函数都有函数原型,因此C++容易表达重载(overload)一个函数名的概念。亦即它能区分多个函数,即使它们具有相同的名字但有不同的参数。
C++允许进行函数重载:多个函数具有相同的函数名,但有不同的参数表和各自的函数体。只要编译能区分参数表(参数个数和类型),就可以重载一个函数名由于所有C++函数都有函数原型,因此C++容易表达重载(overload)一个函数名的概念。亦即它能区分多个函数,即使它们具有相同的名字但有不同的参数。
C++允许进行函数重载:多个函数具有相同的函数名,但有不同的参数表和各自的函数体。只要编译能区分参数表(参数个数和类型),就可以重载一个函数名由于所有C++函数都有函数原型,因此C++容易表达重载(overload)一个函数名的概念。亦即它能区分多个函数,即使它们具有相同的名字但有不同的参数。
C++允许进行函数重载:多个函数具有相同的函数名,但有不同的参数表和各自的函数体。只要编译能区分参数表(参数个数和类型),就可以重载一个函数名。由于所有C++函数都有函数原型,因此C++容易表达重载(overload)一个函数名的概念。亦即它能区分多个函数,即使它们具有相同的名字但有不同的参数。
C++允许进行函数重载:多个函数具有相同的函数名,但有不同的参数表和各自的函数体。只要编译能区分参数表(参数个数和类型),就可以重载一个函数名。由于所有C++函数都有函数原型,因此C++容易表达重载(overload)一个函数名的概念。亦即它能区分多个函数,即使它们具有相同的名字但有不同的参数。
C++允许进行函数重载:多个函数具有相同的函数名,但有不同的参数表和各自的函数体。只要编译能区分参数表(参数个数和类型),就可以重载一个函数名。由于所有C++函数都有函数原型,因此C++容易表达重载(overload)一个函数名的概念。亦即它能区分多个函数,即使它们具有相同的名字但有不同的参数。
C++允许进行函数重载:多个函数具有相同的函数名,但有不同的参数表和各自的函数体。只要编译能区分参数表(参数个数和类型),就可以重载一个函数名
double abs(double num)
{
return ((num < 0 ) ? -num : num);
}
long abs(long num)
{
return ((num < 0) ? -num : num);
}
多个同名函数的原型中不允许只有返回类型不相同,而函数名和参数表完全相同的情况。
异常处理机制
异常处理的意义
异常处理是C++语言的一个主要特征,它提出了出错处理更加完美的方法。
出错处理程序的编写不再繁琐,也不须将出错处理程序与“通常”代码紧密结合。
异常处理的意义
异常处理是C++语言的一个主要特征,它提出了出错处理更加完美的方法。
1.出错处理程序的编写不再繁琐,也不须将出错处理程序与“通常”代码紧密结合。
2.错误发生是不会被忽略的——如果被调用函数需发送一条出错信息给调用函数,它可向调用函数发送描述出错信息的对象。如果调用函数没有捕捉和处理该错误信号,在后续时刻该调用函数将继续发送描述该出错信息的对象,直到该出错信息被捕捉和处理。
异常处理的方法
1.抛出异常
throw 表达式;
2.异常捕获
try
{
语句*;
}
[ catch (类型1 [变量名1]) { 语句; }
catch (类型2 [变量名2]) { 语句; }
…
catch (类型n [变量名3]) { 语句; } ]
————————异常捕获
1.try块
关键字try引导可能出错的语句块。
2.异常处理器
异常处理器紧随try块之后,处理的方法由关键字catch引导。
如果一个异常信号被抛出,异常处理器中第一个参数与异常抛出对象相匹配的函数将捕获该异常信号,然后进入相应的catch子句,执行异常处理程序。
3.异常类型
4.异常规格说明:异常规格说明再次使用了关键字throw,函数的所有潜在异常类型均随着关键字throw而插入函数说明中。所以函数说明可以带有异常说明如下:
void f() throw (toobig, toosmall, divzero);
例如:
#include <iostream>
using namespace std;
int Mod(const int e1, const int e2) throw (int, long)
{
if (e1 == 0) throw int(e1);
if (e2 == 0) throw long(e2);
return e1 % e2;
}
void main() {
int e1, e2, mod;
cin >> e1;cin >> e2;
try
{
mod = Mod(e1, e2);
cout << e1 << “ mod “ << e2 << “ = “ << mod << endl;
}
catch (int)
{cout << “numerator is 0.” << endl;}
catch (long)
{cout << “cannot be zero.” << endl;}
}
程序运行时,如果我们输入
30294 517
程序的输出是:
30294 mod 517 = 308
如果输入
0 98
则程序的输出是:
numerator is 0.
如果输入
123 0
则程序的输出是:
cannot be zero.
程序运行时,如果我们输入
30294 517
程序的输出是:
30294 mod 517 = 308
如果输入
0 98
则程序的输出是:
numerator is 0.
如果输入
123 0
则程序的输出是:
cannot be zero.程序运行时,如果我们输入
30294 517
程序的输出是:
30294 mod 517 = 308
如果输入
0 98
则程序的输出是:
numerator is 0.
如果输入
123 0
则程序的输出是:
cannot be zero.抛出异常
throw 表达式;
异常捕获
try
{
语句*;
}
[ catch (类型1 [变量名1]) { 语句; }
catch (类型2 [变量名2]) { 语句; }
…
catch (类型n [变量名3]) { 语句; } ] 抛出异常
throw 表达式;
异常捕获
try
{
语句*;
}
[ catch (类型1 [变量名1]) { 语句; }
catch (类型2 [变量名2]) { 语句; }
…
catch (类型n [变量名3]) { 语句; } ] 抛出异常
throw 表达式;
异常捕获
try
{
语句*;
}
[ catch (类型1 [变量名1]) { 语句; }
catch (类型2 [变量名2]) { 语句; }
…
catch (类型n [变量名3]) { 语句; } ]