c++数组

来源:互联网 发布:科大讯飞同声翻译软件 编辑:程序博客网 时间:2024/06/06 16:21

数组介绍

C++ 语言提供了两种类似于 vector 和迭代器类型的低级复合类型——数组和指针。与 vector 类型相似,数组也可以保存某种类型的一组对象;而它们的区别在于,数组的长度是固定的。数组一经创建,就不允许添加新的元素。指针则可以像迭代器一样用于遍历和检查数组中的元素。

而现代的 C++ 程序则更多地使用 vector 来取代数组,数组被严格限制于程序内部使用,只有当性能测试表明使用 vector 无法达到必要的速度要求时,才使用数组。然而,在将来一段时间之内,原来依赖于数组的程序仍大量存在,因此,C++ 程序员还是必须掌握数组的使用方法

数组是由类型名、标识符和维数组成的复合数据类型,类型名规定了存放在数组中的元素的类型,而维数则指定数组中包含的元素个数。

数组定义中的类型名可以是内置数据类型或类类型;除引用之外,数组元素的类型还可以是任意的复合类型。没有所有元素都是引用的数组。

       int a[2]={1,2};
int &b=a;//error
int *p = a ;//ok

数组初始化

如果没有显式提供元素初值,则数组元素会像普通变量一样初始化

在函数体外定义的内置数组,其元素均初始化为 0。
• 在函数体内定义的内置数组,其元素无初始化。
• 不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。
除非显式地提供元素初值,否则内置类型的局部数组的元素没有初始化。此时,除了给元素赋值外,其他使用这些元素的操作没有定义。

与 vector 不同,一个数组不能用另外一个数组初始化,也不能将一个数组赋值给另一个数组,这些操作都是非法的。

指针

指针是存储对象的地址的变量。

一个有效的指针必然是以下三种状态之一:保存一个特定对象的地址;指向某个对象后面的另一对象;或者是0 值。若指针保存0 值,表明它不指向任何对象。未初始化的指针是无效的,直到给该指针赋值后,才可使用它。下列定义和赋值都是合法的:
int ival = 1024;
int *pi = 0; // pi initialized to address no object
int *pi2 = & ival; // pi2 initialized to address of ival
int *pi3; // ok, but dangerous, pi3 is uninitialized
pi = pi2; // pi and pi2 address the same object, e.g.ival
pi2 = 0; // pi2 now addresses no object

void* 指针

C++ 提供了一种特殊的指针类型 void*,它可以保存任何类型对象的地址:
double obj = 3.14;
double *pd = &obj;
// ok: void* can hold the address value of any data pointer type
void *pv = &obj; // obj can be an object of any type
pv = pd; // pd can be a pointer to any type
void* 表明该指针与一地址值相关,但不清楚存储在此地址上的对象的类型。void* 指针只支持几种有限的操作:与另一个指针进行比较;向函数传递void* 指针或从函数返回 void* 指针;给另一个 void* 指针赋值。不允许使用void* 指针操纵它所指向的对象。

指针和引用的比较

虽然使用引用(reference)和指针都可间接访问另一个值,但它们之间有两个重要区别。第一个区别在于引用总是指向某个对象:定义引用时没有初始化是错误的。第二个重要区别则是赋值行为的差异:给引用赋值修改的是该引用所
关联的对象的值,而并不是使引用与另一个对象关联。引用一经初始化,就始终指向同一个特定对象(这就是为什么引用必须在定义时初始化的原因)。
考虑以下两个程序段。第一个程序段将一个指针赋给另一指针:
int ival = 1024, ival2 = 2048;
int *pi = &ival, *pi2 = &ival2;
pi = pi2; // pi now points to ival2
赋值结束后,pi 所指向的 ival 对象值保持不变,赋值操作修改了 pi 指针的值,使其指向另一个不同的对象。现在考虑另一段相似的程序,使用两个引用赋值:
int &ri = ival, &ri2 = ival2;
ri = ri2; // assigns ival2 to ival
这个赋值操作修改了 ri 引用的值 ival 对象,而并非引用本身。赋值后,这两个引用还是分别指向原来关联的对象,此时这两个对象的值相等。

使用指针访问数组元素

C++ 语言中,指针和数组密切相关。特别是在表达式中使用数组名时,该名字会自动转换为指向数组第一个元素的指针:
int ia[] = {0,2,4,6,8};
int *ip = ia; // ip points to ia[0]
通常,在指针上加上(或减去)一个整型数值 n 等效于获得一个新指针,该新指针指向指针原来指向的元素之后(或之前)的第 n 个元素。

指向const 对象的指针(能改变指针的指向而不能改变指针的值)

我们使用指针来修改其所指对象的值。但是如果指针指向const 对象,则不允许用指针来改变其所指的 const 值。为了保证这个特性,C++ 语言强制要求指向 const 对象的指针也必须具有 const 特性:
const double *cptr; // cptr may point to a double that is const
这里的 cptr 是一个指向 double 类型 const 对象的指针,const 限定了cptr 指针所指向的对象类型,而并非 cptr 本身。也就是说,cptr 本身并不是const。在定义时不需要对它进行初始化,如果需要的话,允许给 cptr 重新赋
值,使其指向另一个 const 对象。但不能通过 cptr 修改其所指对象的值
*cptr = 42; // error: *cptr might be const

const 指针(能够改变指针指向的对象的值而不能够改变指针的指向)

除指向 const 对象的指针外,C++ 语言还提供了 const 指针——本身的值不能修改:
int errNumb = 0;
int *const curErr = &errNumb; // curErr is a constant pointer

指向const 对象的 const 指针(指向与值皆不可改变)

还可以如下定义指向 const 对象的 const 指针:
const double pi = 3.14159;
// pi_ptr is const and points to a const object
const double *const pi_ptr = π
0 0