测试用代码:
int li_array[5] = {1, 3, 5, 7, 9};
int * p = li_array;
cout<<*p+1<<","<<*(p+1)<<endl; //正常写法, 输出 2,3 按地址存取运算优先级高于加法运算
cout<< (p+2)[1]<<endl; //输出7, 也就是li_array[3],
(p+2)[1] 写法有些不正常, 但是合法, 正常情况下会写成 *(p+3) 或是 p[3]
结论1: [ ] 是个与*类似的“按地址存取数据”的运算符
1. 在C++中, 按地址存取(写读)内存中数据有两种方法: ① * (地址+偏移量) ② 地址[偏移量]
假设p中保存了一个int型数组的首地址:
例1 * (p+0) //通常简写为 * p
例2 p[0]
例3 (p+1)[0] //p+1先计算, 这是个地址偏移运算, 按INT类型进行一次偏移, 得到一个新的地址
//再计算[0], 这是按地址存取数据运算, 先偏移0个字节, 最后返回偏移后新地址中的int型数据
所以这种写法也可以:
int a=1;
cout<< (&a)[0]; //正常写法是 cout<<a;
2. 对应的, 获得数据的地址也有两个办法 ① &变量名 ② 把数组变量后的[]去掉
声明指针的两个办法① int * p; ② int a[]; //p是指针变量, a是指针常量
3.&变量名是个指针常量, 所以不能 (&变量名)++; 同理数组名也是指针常量, 不能数组名++
之所以是常量, 主要是因为一个变量名总是固定的对应着某一段内存(也就是上一篇的结论)
结论2:
1.所谓"数组", 是用来在一片连续的内存中保存一些数据(每个数据占用的字节数相同)。
int li_array[5] = {1,3,5,7,9}; //申请了20个字节的内存, 每个元素占4个字节。
//赋值前,这20个字节中的很可能会有上次被使用时所“遗留”的数据
//同时, 本次使用结束(程序退出)后, 也会把数据“遗留”在这20个字节中
2.数组名(li_array)是一个指针常量, 保存的是分配给“数组”的那20个字节的内存的首字节地址
3.这个指针常量的基类型, 就是"数组元素"的数据类型
cout<< * (li_array+0)<<","<<*(li_array+1); //输出1,3