2019年4月16日
3.9.1多维数组
我们可以定义多维数组。每一维用一个方括号对来指定,例如:int ia[4][3];
关于多维数组的初始化。为了索引到一个多维数组中,每一维都需要一个方括号对,不然意义就会发生变化。
在C++中,多维数组的索引访问要求对程序员希望访问的每个索引都有一对方括号。
3.9.2 数组与指针类型的关系
数组标识符代表数组中的第一个元素的地址,它的类型是数组元素类型的指针。注意*ia+1; 与*(ia+1)表达式完全不同,解引用操作符比加法运算符的优先级高,所以它先被计算。解引用ia将返回数组的第一个元素的值,然后对其加1。如果在表达式里加上括号,那么ia将先被加1,然后解引用新的地址值。对ia加1将使ia增加其元素类型的大小,ia+1指向数组中的下一个元素。
数组元素遍历则可以通过下表操作符来实现,或者我们也可以通过直接操作指针来实现数组元素遍历。
泛型程序设计:
#include<iostream>
using namespace std;
template<class elemType>
void print(elemType *obegin,elemType *pend)
{
while(pbegin != pend)
{
cout<<*pbegin<<’’;
++pbegin;
}
}
现在我们可以给通用的函数printf()函数传递一对指向任意类型数组的指针,只要该类型的输出操作符已经被定义即可,例如:
int main()
{
int ia[9] = {0,1,1,2,3,3,5,8,13,21};
double da[4] = {3.14,6.28,12.56,25.12};
string sa[3] = {“piglet”,“eeyore”,“pooh”};
print(ia,ia+9);
print(da,da+4);
string(sa, sa+3);
}
标准库提供了一组泛型算法,它们通过-一对标记元素的范围的开始/结束指针来遍历其中的元素。例如,我们可以如下调用泛型算法sort();
#include<algorithm>
int main()
{
int ia[9] = {0,1,1,2,3,3,5,8,13,21};
string sa[3] = {“piglet”,“eeyore”,“pooh”};
sort(ia,ia+6);
sort(sa,sa+3);
}
3.10vector容器类
vector类是随标准C++引入的标准库的一部分,使用时候必须包含其他文件#include<vector>。
我们可以用size()查询vector的大小,也可以用empty()测试它是否为空。vector的元素被初始化为与其类型相关的缺省值,算术和指针类型的缺省值为0,对于class类型,缺省值可以通过调用这类的缺省构造函数获得。我们还可以为每个元素提供一个显示的初始值来完成初始化。例如:
vector<int> ivec(10.-1);//十个元素,每个元素都被初始化为-1;
vector操作符中begin()和end()所返回的迭代器(iterator)使用比较多:
例如:
string word;
for(vector<string>::iterator it = text.begin();
it != text.end(); ++it)
cout<<*it<<‘ ’;
cout<<endl;
注意:任何一个插入的操作都是将增加vector的大小,而不是覆盖掉某个现有的元素,如下面代码:
const int size = 7;
int ia[ size ] = { 0, 1, 1, 2, 3, 5, 8 };
vector< int > ivec( size );
for ( int ix = 0; ix < size; ++ix )
ivec.push_back( ia[ ix ]);
程序结束时ivec包含了14个元素,ia的元素从第八个元素开始插入。
3.11 复数类型
复数(complex number)类是标准库的一部分。为了能够使用它,我们必须包含其相关的头文件:#include<complex>
每个复数都有两个部分:实数部分和虚数部分。叙述代表负数的平方根,这个术语是由笛卡儿首创的。
虚数的定义:
complex<double> purei(0,7);// 0+7i
complex<double> real_num(3);// 3+0i
complex<double> zero;//0+0i
complex<double> purei2(purei);//用另一个复数对象来初始化一个复数对象
compled<double> conjugate[2] =
{complex<double>(2,3),complex<2,-3>};//声明复数对象的数组
3.12typedef名字
typedef机制为我们提供了一种通用的类型定义设施,可以用来为内置的或用户定义的数据类型引入助记符号。
typedef 定义关键字typedef开始,后面是数据类型和标识符。这里的标识符即typedef名字,并没有引入一种新的类型,而只有为现有类型引入了一个助记符号。typedef名字对以出现在任类型名出现的地方。
typedef名字可以被用作程序文档的附注说明,他也能够降低声明的复杂度。注意如果定义:
typedef char* cstring;
extern const cstring cstr;
cstr的类型为 char *const cstr; 而不是const char *cstr;
3.13 volatile限定修饰符
当一个对象的值可能会在编译器的控制或监测之外被改变时候,例如一个被系统时钟更新的变量,那么该对象应该声明成volatile。因此,编译器执行的某些例行优化行为不能应用已指定为volatile的对象上。
volatile修饰符的主要目的是提示编译器,该对象可能在编译器未监测到的情况下被改变。因此编译器不能武断地对引用这些对象的代码作优化处理。
3.14pair类型
pair类也是标准库的一部分,它使得我们可以在单个对象内部把相同类型或不同类型的两个值关联起来。
例如:pair<string,string> author(“James”,”Joyce”);
我们可以用成员访问符号(member access notation)访问pair中的单个元素,为first和second。
3.15类类型
类的定义由关键字class开始,后面是一个标识符,该标识符也被用作类的类型指示符,如complex、vector及Array等等。一般地,一个包括公有的(public)操作部分和私有的(private)数据部分。这些操作被称为类的成员函数(member function)或方法(method)他们定义了类的公有接口(public interface)--即,用户可以在该类对象上执行的操作的集合。
c++六大默认成员函数:构造函数,析构函数,拷贝构造函数,赋值运算符重载函数,取地址操作符重载,const修饰的取地址操作符重载。