与vector 类似,数组也是容器。
数组的缺陷:
1、长度固定
2、没有size 操作,故,无法获取容器大小
3、没有push_back 操作,无法向其添加元素
4、无法更改数组长度,只能创建新的更大的数组,然后,将原数组复制到新数组。
数组维数,必须是大于1 的常量表达式。
也就是说,必须是在编译时,就知道的值。如:const unsigned buf_size = 512;
凡是在运行时才知道的值,都不能定义数组的维数。
const unsigned buf_size = 512, max_files = 20;
int staff_size = 27;
char input_buffer[buf_size]; // 正确, buf_size 是 const
string fileTable[max_files + 1]; // 正确, max_files+1 是常量表达式
const unsigned sz = get_size(); // 错误,get_size() 在运行时才知道,结果值
double salaries[staff_size]; // 错误,staff_size 非const
int test_scores[get_size()]; // 错误,同 get_size()
int vals[sz]; // 错误,同 get_size()
显示初始化数组:
// 显示初始化
const unsigned array_size = 5;
int iarr[array_size] = {0, 1, 2, 3, 4};
// 省略维数
int iarr2[] = {0, 1, 2, 3};
// 相当于:{1, 2, 3, 0, 0}
int iarr3[array_size] = {1, 2, 3};
// 相当于:{"aa", "bb", "cc", "", ""}
string sarr[array_size] = {"aa", "bb", "cc"};
特殊字符:
char ca1[] = {'C', '+', '+'}; // size: 3
char ca2[] = {'C', '+', '+', '\0'}; // size:4
char ca3[] = "C++"; // size:4,末尾自动添加 null
数组不可直接复制或者赋值:
char ca1[] = {'C', '+', '+'};
char ca2[] = ca1;// 错误
vector 的下标类型: vector::size_type
数组的下标类型 : size_t
数组下标超出正确范围,即,发生数组越界。将会产生严重错误。类似的安全问题,称为:缓冲区溢出
const unsigned array_size = 5;
int iarr1[] = {1, 2, 3, 4, 5};
int iarr2[array_size];
for(size_t i=0; i!=array_size; ++i)
iarr2[i] = iarr1[i];
指针,&符号是:取地址操作符(address-of)
string s("This is a string");
string *sp = &s;
注:指针多数用于低级操作,容易产生错误,尽量少用。而通过 vector 、迭代器等方式取代一般的数组、指针的使用。 使用 string 类型,取代 C 风格字符串。
指针定义、初始化
vector<int> *pvec;
int *ip1, *ip2;
string* sp1, sp2; // sp1 是指针,而 sp2 只是 string
指针保存 0 值 或者 NULL ,表明不指向任何对象。(NULL 实际上等价于 0)
特殊的指针:void * ,可以保存任何类型对象的地址
int ival = 1024;
int *pi = 0;
int *pi2 = &ival;
void *pi3 = pi2;
pi = pi2;
数组的算术操作。 *pi2、*pi3 结果相同,但, int *pi3 = iarr + 4 表述更直观。
指针作减法操作,结果是 ptrdiff_t 类型的数据。
使用下标访问数组时,实际上,是使用下标访问了指针。
int iarr[] = {1, 2, 3, 4, 5};
int *pi = iarr;
int *pi2 = &iarr[4];
int *pi3 = iarr + 4;
ptrdiff_t n = pi3 - pi;
int i = *(iarr + 3); // iarr[3], 4
int *pi4 = pi3 - 4; // &iarr[0]
int x = pi3[-4]; // iarr[0] equals to pi3[-4]
// 指向数组的超出末端的地址,可以计算,不能解引用
int *ipend = iarr + 5;
指针是数组的迭代器
const size_t array_size = 3;
int iarr[array_size] = {1, 2, 3};
for (int *pbegin = iarr, *pend = iarr + array_size; pbegin != pend; ++pbegin)
*pbegin = 100;
vector<int> ivec(10, 0);
for (vector<int>::iterator iter = ivec.begin(); iter!=ivec.end(); ++iter)
*iter = 1;
指针和引用的区别
#include <iostream>
#include <string>
#include <bitset>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::bitset;
int main()
{
int ival = 1024, ival2 = 2048;
int *pi = &ival, *pi2 = &ival2;
pi = pi2;
*pi = 5000;
cout << "pi:" << pi << ", pi2:" << pi2 << endl;
cout << "*pi :" << *pi << ", *pi2 :" << *pi2 << endl;
int &ri = ival, &ri2 = ival2;
cout << *(&ri) <<endl;
ri = ri2;
cout << "ri:" << ri << ", ri2:" << ri2 << endl;
cout << "&ri:" << &ri << ", &ri2:" << &ri2 << endl;
system("pause");
return 0;
}
结果如下:
指向指针的指针
#include <iostream>
#include <string>
#include <bitset>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::bitset;
int main()
{
int x = 10;
int *pi = &x;
int **ppi = π
cout << "x:" << x << endl;
cout << "*pi:" << *pi << endl;
cout << "**ppi:" << **ppi << endl;
system("pause");
return 0;
}
结果如下