C++ 指针数组与数组指针, 数组与指针

复习c++基础知识,地基不牢,地动山摇。最近被基础概念搞懵逼了,在此记录复习一下知识点。

一 指针数组和数组指针区别

指针数组:其实就是一个数组,数组每一个元素是相同数据类型的指针 int * ptr[3]
数组指针:其实就是一个指针,它指向的是一个数组,int (*ptr)[3]
他们的区别按照如下的优先级顺序,() > [] > *,我们先看圆括号,然后中括号,最后星。

int *ptr[3],根据优先级规则先看[],首先它是一个数组,然后看*,它是一个指针,综合来说,它是一个数组,数组每一个元素是一个指针,并且是int类型指针
int (*ptr)[3],根据优先级规则,先看(), *ptr是一个指针,然后看[],它是一个数组。综合看,它是一个指针,并且int类型,它指向一个数组元素为3个的数组

二 例子

直接使用代码说明
首先看指针数组的例子

指针数组

//指针数组
#include <iostream>

int main()
{
    int a = 10;
    int b = 7;
    int c = 9;
    
    int * test[3];
    test[0] = &a;
    test[1] = &b;
    test[2] = &c; 

    int nums = sizeof(test)/sizeof(test[0]);

    for (auto i:test)
    {
        std::cout << i << std::endl;
        std::cout << *i << std::endl;
    }

    return 0;
}
结果如下
0x7ffebe9f7080
10
0x7ffebe9f7084
7
0x7ffebe9f7088
9

上面指针数组应该是好理解的,接下来我们看看数组指针的例子

数组指针

//数组指针
#include <iostream>

int main()
{
    int test[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int (*ptr)[3] = nullptr;    
    ptr = test;
    std::cout << "1 : " << ptr << std::endl;

    ptr = &test[0];
    std::cout << "2 : " << ptr << std::endl;

    ptr = &test[1];
    std::cout << "3 : " << ptr << std::endl;

    std::cout << "4 : " << ptr++ << std::endl;

    std::cout << "5 : " << test << std::endl;
    std::cout << "6 : " << test[0] << std::endl;
    std::cout << "7 : " << test[0][0] << std::endl;

    /*
    std::cout << **test << std::endl;

    int *ptr1 = nullptr;
    ptr1 = test[1];
    std::cout << ptr1 << std::endl;
    */

    return 0;
}
结果如下
1 : 0x7ffe2f12a1d0
2 : 0x7ffe2f12a1d0
3 : 0x7ffe2f12a1dc
4 : 0x7ffe2f12a1dc
5 : 0x7ffe2f12a1d0
6 : 0x7ffe2f12a1d0
7 : 1

根据结果可知(1) test是数组首地址和&test[0]是相等的,可以直接赋值给ptr
          (2)  &test[1]和ptr++是相等的,都是对指针的偏移

由于上面的例子牵涉到,指针和数组,所以难度比指针数组难一些,因此我们可以复习一下,指针数组的关系

三 指针与数组

复习基础知识
1 不存在多维数组,多维数组本质是一维数组的模拟
2 数组名是一个常量,(不允许进行赋值),代表是数组的首元素首地址
3 指针是一个变量,具有类型,其占用空间大小与系统相关
4 对数组的数组名取地址(&),其类型为整个数组类型
5 对数组的数组名进行sizeof操作,其值为整个数组的大小
6 数组作为函数形参会变成指针

四 指针与数组的例子

注意上面的第2,第4比较重要需要记住
2 数组名是一个常量,(不允许进行赋值),代表是数组的首元素首地址
4 对数组的数组名取地址(&),其类型为整个数组类型
例子如下
int a[3] = {1, 2, 3};
a 表示a[3]数组的首元素首地址,也就是a[3]中的1值的地址,它是一个int类型
int * b = nullptr;
b = a; //正确
std::cout << b << std::endl;
结果为:0x7ffcf435c784
如果我们对 a 数组名取地址 &a,表达的含义是第4,它的数据类型是对整个数组
b = &a; //错误的,&a表示是一个数组指针,该指针指向一个数组为3维的,每个元素为int类型
int (*c)[3];
c = &a; //正确
std::cout << c << std::cout;
结果为:0x7ffcf435c784

总结,虽然我们的输出结果一致,但是它们的含义却不一样,这点需要注意。

五 多维数组与指针

int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int (*b)[3];
b = a; //正确,规则2
b = &a[0]; //正确 规则4
b = a[0]; //错误,根据规则2,数据类型为 int * ; 正确为 int * c = a[0];
b = &a; //错误,根据规则4,数据类型为 int(* p)[2][3]; 正确为 int(*p)[2][3] = &a;

指针数组复习,已复习完毕,我们再去看看第二个例子,数组指针,就容易理解很多了,今日复习到此结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值