二维数组的地址,以及二维数组的地址写法 , 数组指针,数组指针和二维数组的配合应用

时间:2024-10-18 10:20:46

1、二维数组的地址

int a[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}}

a是二维数组名

(数组的)名字 ==地址

 (行) 父数组(名) = a                         地址

 (列) 子数组  (名 )= a[0]                      一维数组{1,3,5,7}的名字  

                                    a[1]                               一维数组{9,11,13,15}的名字  

                                        a[2]                          一维数组{17,19,21,23}的名字  

                                                                                                     地址

//1 的值的地址 既可以叫做二维数组的首地址,也可以面向列的首地址

a +1    偏移了多少?到了9的地址,       a +2  到了17 的地址    (偏移值很大,取决于一列当中有多少个元素)

a[0]  +1   偏移了多少? 到了3的地址          a[0] +2   到了 5 的地址

a[0]是第一个子数组的地址,同时是第一个子数组的名字

a[1]是第二个子数组的地址,同时是第二个子数组的名字

a[2]是第三个子数组的地址,同时是第三个子数组的名字

如果   int arr{3} = [1,2,3]

int *p = arr;

*p = 1,    *(p+0) = 1   , *(p+1) =2

所以在a[3][4] 中  a[0],*a 表示子数组的地址

验证一下

 

2、二维数组的地址写法应用

 

可以换一种写法

 

还有种写法

总结一下

 

 第三行可以这么理解:

a[1] =  *(a+1);    取内容a +1,       前面再加一个取地址,他两就抵消了

3、数组指针

(定义一个指针去访问二维数组)

第 6 行的 12个数的地址空间其实是连续的

既然地址空间是连续的,可以定义一个p,让 p等于12 个连续的数据 的第一个数据

              (用一层循环也可以啦)

 

但是结果有点失去了二维数组的味道,

哪能不能把一维数组的p  指向数组名呢?

(          int arr[3][4] = {{11,22,33,44},{12,13,15,16},{22,66,77,88}};是个二维数组        

                表示二维数组的地址,可以把二维数组的开头的元素的地址拿到手)

 这样写指针有点不太匹配, 

p =arr;   是一个面向于行的,它的元素每一项都是数组。

int *p  是面向单个整型数的

第7行的p ++    和第6行的arr ++   是两码事,

arr ++跳的是整个数组,而P++跳的是一个整形变量

你拿二者互等的时候,编译一定有警告或者错误的

运行是可以正常运行的,只不过会产生一些风险性的错误

能不能定义一个指针,让指针偏移的时候,也偏移对应大小的数组?

数组指针:定义一个指针,指向一个数组

 int arr[3][4] = {{11,22,33,44},{12,13,15,16},{22,66,77,88}}   可以理解为三个指针

{11,22,33,44}一个指针      {12,13,15,16}另一个指针   {22,66,77,88}另一个指针

每一个指针 (地址)大小都一样

int(*p) 代表是一个指针

int (*p2)[4];

p2 =arr;

 

会发现没有报错

这时候 p2 的属性可以把它当作arr 来玩

 

也可以把数组名当成指针来用

 

包括p2 的偏移也能看出来

  

 

产生这样的原因是左值运算

人类的思想 先用p2,再用p2++,            可是printf对参数是从右面开始取的

 

分开写就好了

//数组指针才是真正等同于二维数组名

4、数组指针和二维数组的配合应用

练习:用函数分装的方式,输出二维数组任意行列的数

一般的步骤呢? 

//提示用户输入行列值

//找出对应行列值的那个数

//打印出来

 

 

也可以稍微加点改动