4.1 数组
数组是由类型名、标识符和维数所组成的复合数据类型。
int array[4] = {0, 1, 2, 3};
4.1.1 数组的定义和初始化
1.数组的维数:必须是值大于等于1的常量表达式。
2.数组的初始化:与c语言相同
3.数组的赋值:不允许数组之间的直接复制和赋值
4.2 指针的引入
4.2.1 指针的定义
指针:指针保存的是一个对象在内存中的地址。
string s("hello c++");
string *p = &s; // &是取地址符
4.2.2 指针的定义和初始化
1. 指针变量的定义
tip:理解指针的声明语句时,建议从右向左阅读。
string *pstring;
/*该句把pstring定义为一个指向string类型的指针变量*/
2. 指针变量可能的取值
指针变量只有三种取值:1. 保存一个特定对象的地址
2. 保存某个对象后面的另一个对象 (不理解)
3. 0值,表示该指针不指向任何对象。(这个0值如果来自变量,那么必须是const类型的变量)
warning:没有初始化的指针变量是十分危险的。
3. void*指针
一种特殊的指针类型,可以保存任何类型对象的地址。但只支持几种特定的操作,不允许通过void*类型的指针来操纵指向对象的值。
string s = "hello, c++";
string *p1 = &s;
void* p2 = &s; // right
4.2.3 使用指针访问数组元素
数组的数组名为指向数组第一个元素的指针。
4.2.4 指针和const限定符
4.2.4.1 指向const对象的指针
1.c++11强制要求指向const类型的对象的指针也具有const性质。
const double pi = 3.14;
double *p1 = pi; // error
const double *p2 = pi; //right
2.这里的const指明的是指针cptr指向的对象为const,而非cptr本身为const。
const double *cptr; // cptr may point to a double that is const
3.cptr所指向的对象是可以改变的,但是不可以通过cptr来改变其指向的对象的值。
*cptr = 42; //error, cptr is a point to a const double
4.使用void*来保存const对象的地址时,也必须使用const void*。
void *p1 = pi; // wrong
const void *p2 = pi; // right
5.关于第三点的重述,指向const对象的指针所指的对象的值并不一定是不可改变(好奇怪啊)。
int main()
{
double pi = 3.14;
const double *p1 = π
cout << *p1 << endl;
return 0;
}
/* ouput */
/*
3.14
*/
4.2.4.2 const指针
int num = 0;
int *const p = #
这里的p是指向int类型对象的const指针。
不可以改变const指针的值,但可以通过指针改变所指向的对象的值。
int main()
{
int num = 0;
int* const p = #
p = 0; //wrong
*p = 3; //right
cout << "num = " << num << endl;
return 0;
}
4.3 C风格字符串
大量错误的来源,在c语言书籍中有具体阐述,不再赘述。
4.3.1 创建动态数组
c++使用new和delete表达式实现在自由存储区中分配存储空间。
1. 动态数组的定义
只需指定数组类型和维数,通过new返回新分配数组的首地址。
int *p = new int[10]; // array of 10 uninitialized ints
2. 动态分配数组的初始化
类类型通过默认构造函数初始化,内置类型无初始化。
也可通过在后面加一对圆括号进行初始化。
int main()
{
int* p = new int[1]();
cout << *p << endl;
return 0;
}
/*output*/
/*
0
*/
3. 动态分配空间的回收
delete[] p;
4.3.2 使用数组初始化vector
使用数组初始化vector必须指出初始化式的第一个元素和最后一个元素的下一位置的地址。
int main()
{
const int array_size = 6;
int array[array_size] = { 0,1,2,3,4,5 };
vector<int> vec(array, array + array_size);
for (vector<int>::size_type i = 0; i < array_size; i++)
cout << vec[i] << endl;
return 0;
}
/* output */
/*
0
1
2
3
4
5
*/