数组指针

/*
 数组指针
 本质上是指针,是数组类型的指针,指向一个数组类型,每次偏移1是+整个数组长度的字节数
 */

#include <iostream>
using namespace std;

int main() {
    // 一、一维数组的三个地址分析
    int a[3] = {2,3,4};
    
    // 以下3个变量都是指首元素的地址,但是a与&a[0]指针类型是int,而&a指针类型是不一样的,是int (*)[3]
    cout<<a<<endl;
    cout<<&a[0]<<endl;
    cout<<&a<<endl;
    cout<<endl;
    /*
     0x7ff7bfeff31c
     0x7ff7bfeff31c
     0x7ff7bfeff31c
     */
    
    // 二、指针的偏移量分析
    // 不同类型的指针不能赋值
    int *p = a; //正确
    p = &a[0]; //正确
//    p = &a; //错误,&a的类型为 int (*)[3]
    
    // 本质:查看+1的偏移量,到底是偏移多少个字节
    cout<<a+1<<endl; //偏移了1个int类型,4个字节
    cout<<&a+1<<endl; //偏移了3个int类型,12个字节,相当于加了整数数组的长度,&a就是数组指针
    /*
     输出:
     0x7ff7bfeff320  由 0x7ff7bfeff31c +4字节 一个整数类型
     0x7ff7bfeff328  由 0x7ff7bfeff31c +12字节 一个长度为3数组类型
     */
    
    // 三、数组指针:本质上是指针,是指向数组的指针
    int (*p1)[3] = &a;
//    int (*p2)[4] = &a; //错误,a的类型是 int (*)[3],而定义的p2类型为 int (*)[4],两者也是不同类型,不能赋值
    /*
     注意 *p要加上括号,因为[] 优先于*,如果是 *p1[3] 表示的是指针数组(是一个数组,里面存储的是地址),两种不同的概念
     因为p1是a的地址,所以*p1就是a,那要取a的元素,相当于 a[0] 等价于 (*p1)[0],a[1] 等价于 (*p1)[1];注意 *p1要打上括号,因为[] 优先于*,如果要取 a[0]地址,相当于 &(*p1)[0];
     */
    
    //p1是a的地址,那么*p1 是a本身,*p1==a
    cout<<a<<endl;
    cout<<*p1<<endl;
    
    // 由于 *p1==a ,同时加[0] ,那么 a[0]==(*p1)[0]
    cout<<a[0]<<endl;
    cout<<(*p1)[0]<<endl;
    
    // 通过指针进行赋值
    (*p1)[0] = 100;
    cout<<a[0]<<endl;
    cout<<(*p1)[0]<<endl; //(*p1)[0]与a[0]等价
    
    // 由于 a[0]==(*p1)[0] ,两加再加&,&a[0]与&(*p1)[0]也是等价的
    cout<<&a[0]<<endl;
    cout<<&(*p1)[0]<<endl;
    
    // 四、指针数组与数组指针区别
    /*
     指针数组:本质上是数组,里面每个元素是装的地址 int *p[3]; 定义一个3个长度的指针数组,每个元素都是地址
     数组指针:本质上是指针,int (*p)[3]; p是一个指针,指向了一个长度为3的数组 如果p+1,是偏移一个数组的长度
     */
    
    
    return 0;
}