数组

vector 类型相同,数组也是存放类型相同的对象的容器,与 vector 不同的是,数组的大小是确定不变的,不能随意向数组中添加元素。

定义和初始化内置数组

数组的维度是编译时已知的,维度必须是一个常量表达式。

和内置类型一样,如果在函数内部定义了某种内置类型的数组,那么默认初始化会令数组含有未定义的值。

显示初始化数组元素

  • 可以对数组元素进行列表初始化,此时允许忽略数组的维度,如果没有明确指明数组的维度,编译器会根据初始值的数量计算并推测出来。
  • 如果指明了数组的维度,那么初始值的总数量不能超出指定的大小。
  • 如果维度比提供的初始值数量大,则用提供的初始值初始化靠前的元素,剩下的元素被初始化为默认值。
const unsigned sz = 3;
int ia1[sz] = { 0,1,2 };	//ia1含有三个元素
int a2[] = { 0,1,2 };		//a2 是含有三个元素的数组
int a3[5] = { 0,1,2 };		//a2 是含有5个元素的数组,前三个元素分别是0,1,2,后两个元素默认初始化
int a4[2] = { 1,2,3 };		//错误,初始值过多

字符数组的特殊性

字符数组可以使用字符串字面值进行初始化,当使用这种方式时,一定要注意字符串字面值末尾还有一个空字符,这个空字符也会像字符串其它字符一样被拷贝到字符数组中。

char a1[] = { 'C','+','+' };	//列表初始化,没有空字符
char a2[] = { 'C','+','+',''};	//列表初始化,含有显示的空字符
char a3[] = "C++";	//自动添加表示字符串结尾的空字符
const char a4[6] = "Daniel";	//错误,没有空间容纳空字符

不允许拷贝和赋值

不能将数组的内容直接拷贝给其它数组作为初始值,也不能用数组为其它数组赋值:

int a[] = {0,1,2};
int a2[] = a;	//错误,不允许使用一个数组初始化另一个数组
a2 = a;	//错误,不能将数组直接赋值给另外一个数组

访问数组元素

数组元素可以使用范围 for 语句或下标运算符来访问。

在使用数组下标的时候,通常将其定义为 size_t类型,size_t 是一种与机器无关的无符号类型,它被设计的足够大以便能表示内存中任意对象的大小。size_t 定义在头文件 cstddef 中。

指针和数组

数组的元素也是对象,对数组元素使用下标运算符得到该数组指定位置的元素,对数组元素使用取地址符就能得到指向该元素的指针。

string nums[] = { "one","two","three" };
string *p = &nums[0];

数组还有一个特性:很多用到数组名的地方,编译器会自动将其替换成为一个指向数组首元素的指针。

string *p2 = nums;	//等价于p2 = &nums[0]

使用数组作为一个auto变量的初始值时,推断得到的类型是指针而非数组。

使用decltype关键字时,编译器不会将数组以指针看待。

int ia[] = {0,1,2,3,4,5,6,7,8,9};
auto ia2(ia);	//ia2是一个整型指针,指向ia的第一个元素

decltype(ia) ia3 = {0,1,2,3,4,5,6,7,8,9};

标准库函数 begin 和 end

C++11新标准引入的两个函数 beginend。因为类不是类类型,因此这两个函数不是成员函数,正确的使用方法是将数组作为它们的参数。

int ia[] = {0,1,2,3,4,5,6,7,8,9};
int *beg = begin(ia);
int *end end(ia);	//返回数组尾元素下一个位置的指针

指针运算

指针的基本运算包含:解引用,递增,比较,与整数相加,两个指针相减。

  • 两个指针相减的前提是两个必须指向同一个数组当中的元素,两个指针相减的结果是 ptrdiff_t 的标准类型,它定义在 头文件 <cstddef> 中, ptrdiff_t 是一种带符号类型。、
  • 给指针加上一个整数,得到的新指针仍需指向同一数组的其它元素,或者指向同一数组的尾元素的下一个位置。
  • 只要两个指针指向同一个数组的元素,或者指向该数组的尾元素的下一个位置,就能利用关系运算符对其进行比较。

下标和指针

int ia = {0,2,4,6,8};

int i = ia[2];	//ia[2]是(ia+2)所指向的元素
int *p = ia;	//p指向ia的首元素
i = *(p+2);		//等价于ia[2]

int *p = &ia[2];	//p指向索引为2的元素
int j = p[1];		//p[1]等价于*(p+1),就是ia[3]表示的那个元素
int k = p[-2];		//p[-2]等价于就是ia[0]表示的那个元素

C 风格字符串

尽管C++支持C风格字符串,但在C++程序中最好不要使用C风格字符串,这是因为C风格字符串不仅使用起来很不方便,而且极易引发程序漏洞,是诸多安全问题的根本原因。

C 标准库string函数

C语言标准库提供了一组函数,这些函数可以用于操作C风格字符串,它们定义在 <cstring> 中。

传入此类函数的指针必须是指向以空字符结束的字符数组。

混用string对象和C风格字符串

任何出现字面值的地方都可以用以空字符结束的字符数组来替代:

  • 允许使用以空字符结束的字符数组来初始化 string 对象或为 string 对象赋值。
  • string 对象的加法运算中,允许使用以空字符结尾的字符数组作为其中一个运算对象。

但是如果程序中需要使用一个C风格字符串,不能直接使用 string 对象来代替它。

不能用string对象直接初始化指向字符的指针,为了完成这个功能,string 提供了 c_str 的成员函数,c_str函数的返回值是一个C风格字符串,结果指针的类型是 const char*

使用数组初始化vector

不允许使用一个数组为另一个内置类型的数组赋值。不允许使用vector对象初始化数组,但是可以使用数组来初始化vector对象。要实现这一目的,只需指明要拷贝区域的首元素地址和尾元素地址。

int int_arr[] = {0,1,2,3,4,5};
vector<int> ivec(begin(int_arr),end(int_arr));
vector<int> subVec(int_arr + 1,int_arr + 4);	//也可以只用数组的一部分初始化vector

注意:

现代C++程序应该尽量使用 vector 和迭代器,避免使用内置数组和指针;应该尽量使用 string ,避免使用C风格字符串。

原文地址:https://www.cnblogs.com/xiaojianliu/p/12498476.html