【C/C++】数组指针 与二维数组

1、二维数组

二维数组,有行,有列。二维数组可以看成有多个一维数组构成的,是多个一维数组的集
合,可以认为二维数组的每一个元素是个一维数组。
例:
int a[3][5];
定义了一个3行5列的一个二维数组。
可以认为二维数组a由3个一维数组构成,每个元素是一个一维数组。
回顾:
数组的名字是数组的首地址,是第0个元素的地址,是个常量,数组名字加1指向下个
元素
二维数组a中 ,a+1 指向下个元素,即下一个一维数组,即下一行。
 #include <stdio.h>
2 int main(int argc, char *argv[])
3 {
4 int a[3][5];
5 printf("a=%p\n",a);
6 printf("a+1=%p\n",a+1);
7 return 0;
8 }

2、数组指针的概念:

本身是个指针,指向一个数组,加1跳一个数组,即指向下个数组。
数组指针的作用就是可以保存二维数组的首地址

3、数组指针的定义方法

指向的数组的类型(*指针变量名)[指向的数组的元素个数]
int (*p)[5];//定义了一个数组指针变量p,p指向的是整型的有5个元素的数组
p+1 往下指5个整型,跳过一个有5个整型元素的数组。
 void test1()
2 {
3 int a[3][5];//定义了一个3行5列的一个二维数组
4 int(*p)[5];//定义一个数组指针变量p,p+1跳一个有5个元素的整型数组
5
6 printf("a=%p\n",a);//第0行的行地址
7 printf("a+1=%p\n",a+1);//第1行的行地址,a和a +1差20个字节
8
9 p=a;
10
11 printf("p=%p\n",p);
12 printf("p+1=%p\n",p+1);//p+1跳一个有5个整型元素的一维数组
13 }
执行结果

数组指针的用法: 作为函数形参,接收二维数组
void funTest1(int (*p)[3] ){
  p[0][1]=999;

  int i,j;
  for(i=0;i<2;i++){
      for(j=0;j<3;j++){
          printf("item[%d][%d] =%d\n",i,j,p[i][j]);

        }
    }
}

4、各种数组指针的定义:

(1)、一维数组指针,加1后指向下个一维数组
int(*p)[5] ;
配合每行有5个int型元素的二维数组来用
int a[3][5]
int b[4][5]
int c[5][5]
int d[6][5]
…..
p=a;
p=b;
p=c;
p=d;
都是可以的~~~~

(2)、二维数组指针,加1后指向下个二维数组
int(*p)[4][5];
配合三维数组来用,三维数组中由若干个4行5列二维数组构成
int a[3][4][5];
int b[4][4][5];
int c[5][4][5];
int d[6][4][5];
这些三维数组,有个共同的特点,都是有若干个4行5的二维数组构成。
p=a;
p=b;

p=c;
p=d;
(3)、三维数组指针,加1后指向下个三维数组
int(*p)[4][5][6];
p+1跳一个三维数组;
什么样的三维数组啊?
由4个5行6列的二维数组构成的三维数组
配合:
int a[7][4][5][6];
(4)、四维数组指针,加1后指向下个四维数组,以此类推。。。。

5、容易混淆的内容:

指针 数组 :是个数组,有若干个相同类型的指针构成的集合
        int *p[10];
        数组p有10个int *类型的指针变量构成,分别是p[0] ~p[9]
数组 指针 :本身是个指针,指向一个数组,加1跳一个数组 (即步长为整个数组)
        int (*p)[10];
        P是个指针,p是个数组指针,p加1指向下个数组,跳10个整形。
指针的 指针
        int **p;//p是指针的指针
        int *q;
        p=&q;

(重要)6、数组名字取地址:变成 数组指针

一维数组名字取地址,变成一维数组指针,即加1跳一个一维数组
int a[10];
a+1 跳一个整型元素,是a[1]的地址
a和a+1 相差一个元素,4个字节
&a就变成了一个一维数组指针,是 int(*p)[10]类型的。
(&a) +1 和&a相差一个数组即10个元素即40个字节

(重要)7、数组名字和指针变量的区别:

int a[10];
int *p;
p=a;
相同点:
a是数组的名字,是a[0]的地址,p=a即p也保存了a[0]的地址,即a和p都指向a[0],所
以在引用数组元素的时候,a和p等价

不同点:
1、 a是常量、p是变量
可以用等号’=’给p赋值,但是不能用等号给a赋值
2、 对a取地址,和对p取地址结果不同
因为a是数组的名字,所以对a取地址结果为数组指针
p是个指针变量,所以对p取地址(&p)结果为指针的指针。

(重要)8、多维数组中指针的转换:

在二维数组中,行地址 取 * 不是取值得意思,而是指针降级的意思,由行地址(数组
指针)变成这一行第0个元素的地址。取*前后还是指向同一个地方,但是指针的类型不一样
了。
1 //二维数组的数组名降级问题
2 //二维数组的数组名默认是一个行指针,加1保存下一行的首地址
3 //二维数组的数据名取*,表示地址的降级,意味着行指针降级为列指针,加1保存下一个元
素的地址
4
5 //一维数组的数组名默认是一个列指针,加1保存下一个元素的地址
6 //一维数组的数组名取&,则是地址的升级,将列指针升级为行指针,加1保存下一行元素的
首地址
7 void test3()
8 {
9 int a[3][5];
10 printf("a=%p\n",a);
11 printf("a +1=%p\n",a+1);
12
13 printf("*a =%p\n",*a);// *a变成了第0行第0列元素的地址
14 printf("(*a)+1 =%p\n",(*a)+1 ); //结果为第0行第1列元素的地址
15 }

执行结果

补充:数组元素的几种表达表示

指针法表达二维数组元素:

int arr[2][3]={{1,2,3},{5,6,7}}; //二维数组名是一个数组指针

int (*p)[3]=arr; //数组指针 

下面表达式成立:

p[1][2]=*(*(p+1)+2) =*(*(arr+1)+2

#include <stdio.h>

int main() {

    int a[2][3]={{11,22,33},{55,66,77}};
    int (*p)[3]=a; //数组指针

    printf("*(*(p+1)+2) = %d\n",*(*(p+1)+2));
    printf("*(*(a+1)+2) = %d\n",*(*(a+1)+2));
    
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值