利用指针遍历数组

/*
 利用指针遍历数组
 数组的本质是首元素的地址,而地址是就是指针。
 指针是可以进行算术运算的,这种运算是指地址的偏移
 */

#include <iostream>
using namespace std;

int main() {
    // 一、数组的本质
    // 数组的本质是首元素的地址,首元素是a[0],&a[0]是首元素地址 ,a[0]元素是整数,所以此时a是一个整型指针 a与&a[0]是等价的
    int a[5] = {3,4,5,6,7};
    cout<<a<<endl; //数组a,a是一个地址,是首元素的地址
    cout<<a[0]<<endl; //首元素的值
    cout<<&a[0]<<endl; //对首元素进行取地址&,a 与 &a[0]都是指地址
    cout<<endl;
    /*
     输出:
     0x7ff7bfeff2f0
     3
     0x7ff7bfeff2f0
     */
    
    // 二、指针的偏移
    /*
     指针偏移是指指针做算术运算,可以向用+向右偏移,-向左偏移,这个+1是指偏移了指针类型的字节数
     通过地址偏移来访问a数组各个元素(数组是一个连续的空间)
     p表示首元素地址,p+1表示下一个元素地址(下标为1),p+2为下标为2元素的地址
     注意:因为p是整型指针,+1表示向右偏移了4个字节,刚好从a首元素地址偏移到下一个元素的首地址
     */
    // 定义一个整型指针p,指向数组a
    // 1.通过指针偏移来获取元素的值
    int *p = a; //或  =&a[0]; 两者等价
    cout<<*p<<endl;
    cout<<*(p+1)<<endl; // 由于p是数组首元素地址,p+1是下标为1元素的地址 *(p+1)取对应地址空间的值
    cout<<*(p+2)<<endl;
    cout<<*(p+3)<<endl;
    cout<<*(p+4)<<endl;
    cout<<endl;
    /*
     输出:
     3
     4
     5
     6
     7
     */
    
    // 2.通过指针偏移并*操作符修改数组元素的值
    cout<<a[2]<<endl;
    *(p+2) = 100; //修改对应地址的值
    cout<<a[2]<<endl; //a[2]的值改变了
    cout<<endl;
    /*
     输出:
     5
     100
     */
    
    // 三、通过指针遍历数组
    // 方式一:
    for(int i=0;i<5;i++){
        cout<<*(p+i)<<endl; //p是首元素的地址,i是指偏移量,p的值没改变
    }
    cout<<p<<" "<<&a[0]<<endl; //p的值,与a[0]地址作对比
    cout<<endl;
    /*
     输出:
     3
     4
     100
     6
     7
     0x7ff7bfeff2f0 0x7ff7bfeff2f0
     */
    
    // 方式二:
    for(int i=0;i<5;i++){
        cout<<*p<<endl;
        p++; //p的值一直在变量,一直在向后偏移1
        
//        cout<<*(p++)<<endl; //等同于上面
    }
    cout<<p<<" "<<&a[0]<<endl;
    cout<<endl;
    /*
     输出:
     3
     4
     100
     6
     7
     0x7ff7bfeff304 0x7ff7bfeff2f0
     */
    
    // 方式三:[]本质上是地址偏移运算符号,下标为偏移量,地址+[偏移量]
    p = a;
    for(int i=0;i<5;i++){
        cout<<p[i]<<endl; //与a[i]是等价的,但p是变量(可以指向新地址),a是常量(不能修改)
    }
    cout<<p<<" "<<&a[0]<<endl;
    /*
     输出:
     3
     4
     100
     6
     7
     0x7ff7bfeff2f0 0x7ff7bfeff2f0
     */
    
    // 总结:*(p+i) 与 p[i] 与 a[i] 等价,当然 *(i+p), 2[p]也是等价的,因为[] ,+ 是地址偏移运算符,前后没有关系
    
    return 0;
}