一、定义和初始化数组
1. int array[10];
2. const int a = 10;
int array[a];
3. int array[f()]; //当f()的返回值是一个常量时正确
4. int array[10] = {0,1,2,3,4,5,6,7,8,9};
5. int array[10] = {1,2,3};
6. int array[10] = {0}; //全部元素初始化为0
7. int array[10] = {1} //array[0] = 1,其他都为默认值0
8. int array[] ={ 1,2,3} //array含3个元素
二、数组不允许拷贝和赋值
不允许使用一个数组初始化另外一个数组,形如 int a[] = {1,2}; int a2[] = a;
不允许把一个数组直接赋值给另外一个数组,形如 int a[] = {1,2}; int a1[] = {3,4}; a1 = a;
三、复杂的数组声明
1. int *ptrs[10]; //声明了一个数组,含有10个整形指针
2. int &refs[10] = ... //错误,不存在元素为引用的数组
3. int (*ptr)[10] = &arrar; //ptr是一个指向数组的指针
4. int (&ref)[10] = array; //ref是一个数组的引用
5. int *(&ref)[10] = array; //ref是一个元素为指针的数组的引用
四、指针和数组
1. string nums[] = {"one","two","three"};
string *p = &nums[0]; //p指向数组的第一个元素
string *p1 = &nums; //与上一行等价,p1也指向数组的第一个元素
2. int a[3] = {1,2,3};
auto a2 = a; //此时,a2是一个地址,指向数组的第一个元素
auto a2(a); //效果相同
decltype(a) a3 = {1,2,3,4,5}; //一个例外,这里decltype(a)等价于int [] 类型
当使用数组名给其他变量赋值时,数组名代表的就是数组第一个元素的地址,但是反过来,不允许用指针变量给数组变量赋值。
3. int a[3] = {1,2,3};
int *p = a;
++p; //这里++p指向a[1],不能直接++a的原因是,a是一个不能修改的值(左值)
4. int *e = &a[4]; //首先,输出a[4]时会输出意想不到的东西
//这里数组a只有3个元素,但语法没错,e仍然可以得到后面紧跟着的那个地址
//只是对那个地址表示的变量进行解引用操作*e得到的是意想不到的东西。。。
//这里e的地址 004FF99C与&a[2]的地址 004FF998相差4个字节,++e输出的是004FF9A0
5. C++11标准库begin和end
int a[] = {1,2,3,4,5,6,7,8};
int *beg = begin(a); //返回首元素的地址
int *last= end(a); //返回尾元素的下一位置的地址,出了“门”的第一个地址
6. 指针后面加[]
#include<iostream>
using namespace std;
void main()
{
int a[3] = { 1, 2, 3 };
int *p = a;
cout << p[0] << endl;//输出1
cout << p + 1 << endl;//输出地址
cout << p[2] << endl;//输出3
cout << p[3] << endl;//输出一个很大的数
}
五、指针运算
1. int a[5] = {1,2,3,4,5};
int *p = a; //p指向数组的第一个元素
int *p1 = p+4; //p1指向数组的第五个元素(而不是第二个元素),指针地址的增加长度取决于这个指针所指向的变量的类型
2. 指针和下标
int a[5] = {1,2,3,4,5};
int *p = a; //这时p使用下标的方式与数组名相同
int *p1 = &a[2] //这时p1还可以使用负数当下标,如p1[-1],表示a[1]
3. sizeof的区别
#include <iostream> #include <stdio.h> using namespace std; void fun(int arr[]) { cout << sizeof(arr) << endl; } int main() { int a[5] = { 1, 2, 3, 4, 5 }; cout << sizeof(a) << endl;//输出20 int *p = a; cout << sizeof(p) << endl;//输出4 fun(a);//输出4 return 0; }
这里要说明的是,sizeof数组的时候,大小为整个数组的大小,sizeof指针的时候,大小为4,当数组作为函数的实参传入形参后,其实是作为指针传入的。
4. 数组的地址
#include<iostream>
using namespace std;
void main()
{
short tell[10];//声明一个20个字节的数组
cout << tell << endl;//第一个元素的地址
cout << &tell << endl;//整个数组的地址
cout << tell + 1 << endl;//相比上面增加了2个字节
cout << &tell + 1 << endl;//相比上面增加了20个字节
}
从数字上来说,这两个地址相同;但从概念上来说,tell(&tell[0])是一个2字节内存块的地址,而&tell是一个20字节内存块的地址。
六、指针数组和数组指针
1.指针数组,顾名思义指的是元素是指针的数组。
int *ptrs[10]; //声明了一个数组,含有10个整形指针
2.数组指针,指向数组的指针
int (*ptr)[10] = &arrar; //ptr是一个指向数组的指针
int (*p)[5]; //声明了一个数组指针