数组和指针常常伴随一块,傻傻的分不清楚。
今天在这里就系统的总结一下数组和指针问题。
数组在数据结构中占有十分重要的地位。数组在内存中连续存储的。在使用之前要对其进行声明定义。声明定义时其大小必须是确定的常量,而不能是变量。同时声明定义要进行初始化。对于二维数组,在初始化时可以省略行,但是列不能省去。数组名是首地址,可以作为赋值的右部分赋给指针。通过指针访问数组元素。数组的索引是从0开始的,一旦超出数组边界,[]操作将会报错。数组可以作为类的成员变量,当数组大小为零或者为空时,这个数组占用0个字节。这个数组也被称为柔性数组或者动态数组。这种数组能够变长,可以有效防止越界问题。
二维数组的一个[]操作也表示指针,指向该行的第一个元素。例如定义char a[10][5],那么a[4](注意下表从0开始)指向的就是第5行的第一个元素,即 *a[4] 等于 a[4][0]。而此时的步长就是1(类型是char)。那么*(a[4]+1)就是a[4][1]。而如果而a[4 +1]其加一的步长是5(每行5个元素)个1(每个char元素占用1个字节)。
数组名称表示数组的首地址。例如:
char a[10] = {0,1,2,3,4,5,6,7,8,9},那么a就表示&a[0]。而&a也表示为数组的首地址,但是这个首地址与上面名称所表示的首地址虽然值相同但是意义不同。a属于char *指针,而&a属于char(*)[10]指针。
如果定义一个指针为 char *p = &a +1;那么p指向哪里呢?这里的&a+1应该指向a[10](如果存在的话),但是p-1却是指向a[9]。这是因为p的指针类型与&a不是一种类型,等号右边的+1步长是与&a类型一致,而p-1的步长是与p的类型一致。
指针是存放地址的变量,一般为int型。指针的步长是与指针指向的类型相关,这也很好的解释了上述的步长问题。指针可以进行[]操作。例如声明一个char *p;那么p[1]就表示p+1;其步长就是其类型相关的量,这里就表示指针变量在内存中移动了4位,指向下一个变量,指向的位置移动了一个类型的长度(这里是1)。
在STL中vector包装的就是数组,这也是vector为什么能够快速随机访问的原理了。而list的优势在于频繁的插入和删除。其封装的是链表,这以后也是经常会碰到的。这里就不再展开。