数组与指针
二维数组与指针:
先上代码:
#include<stdio.h>
int main(void) {
//二维数组与指针
int array[4][3] = {
{12,5,6},
{26,34,16},
{15,48,59},
{64,42,96}
};
//数组地址,行地址,元素地址均相同
printf("&array = %p,array = %p,array[0] = %p,&array[0] = %p,&ayyar[0][0] = %p\n", &array, array, array[0], &array[0],&array[0][0]);
//+1时,可以分辨各地址的步长
//printf("&array+1 = %p,array+1 = %p,array[0]+1 = %p,&array[0]+1 = %p,&ayyar[0][0]+1 = %p\n", &array+1, array+1, array[0]+1, &array[0]+1, &array[0][0]+1);
//元素地址解引用
printf("*&array[0][0] = %d,array[0] = %d\n", *&array[0][0], *array[0]);
// 行地址解引用
//第一级
printf("*&array[0] = %p,*array = %p\n", *&array[0], *array);
printf("*&array[0]+1 = %p,*array+1 = %p\n", *&array[0]+1, *array + 1);
//双重解引用
printf("**&array[0] = %d,**array = %d\n", **&array[0], **array);
//数组地址解引用
//第一级(数组行地址,步长为:列数个存储单元)
printf("*&array = %p\n", *&array);
printf("*&array+1 = %p\n", *&array + 1);
//双重解引用(为元素地址,步长为:1存储单元)
printf("**&array = %p\n", **&array);
printf("**&array+1 = %p\n", **&array + 1);
//三重解引用(为值)
printf("***&array = %d\n", ***&array);
int * b;
int (* c)[3];
int(*d)[4][3];
int * e[3];
b = array[0];
b = &array[0][0];
c = &array[0];//不能将其赋值给b,b = &array[0]语句是无效的,会出现警告
c = array;
d = &array;
printf("************************************************\n");
//分析array[1],&array[0][1]与&array[1][0],
printf("&array[0][1] = %p,array[1] = %p\n", &array[0][1], array[1]);
printf("&array[1][0] = %p,array[1] = %p\n",&array[1][0], array[1]+1);
printf("************************************************\n");
printf("&array[0] = %p,&array[1] = %p,&array[0]+1 = %p,&array[1] + 1 = %p\n", &array[0], &array[1],&array[0]+1, &array[1]+1);
return 0;
}
二维数组有如下定义:
int array[m][n]是含有m行×n列个元素的二维数组,
下述用数组名表示的地址是常量,不支持自加、自减操作
二维数组首元素地址为(元素地址):
&array[0][0] == array[0],步长为1个存储单元
二维数组首行元素地址为(行地址):
&array[0] == array,步长为n个存储单元,级别为 int ()[n]
二维数组整个数组的地址为(数组地址):
&array,步长为m×n个存储单元,级别为int ()[m][n]
有:&array == array == &array[0] == array[0] == &array[0][0]
&array[0][0] + 1 == array[0] + 1 == 指向首行首元素的下一个元素的地址,步长:1
&array[0] + 1 == array + 1 == 指向下一行的行地址,步长为:n
&array + 1 == 指向跳过整个数组的下一个地址。步长:m×n
元素地址解引用:
*&array[0][0] == *array[0] == array[0][0] == 第一个元素
行地址解引用:
一级解引用:
*&array[0] == *array == 该数组首行首元素地址(即等于&array[0][0]和array[0])
*&array[0]+1 == *array + 1 等于加一个存储单元,步长为:1
双重解引用:
**&array[0] == **array == array[0][0] 首行首元素的值
数组地址解引用:
一级解引用:
*&array == 数组行地址 ,步长为:n
*&array + 1 == 等于增加n个存储单元
双重解引用:
**&array == 数组元素地址,步长为:1
**&array + 1 == 等于增加一个存储单元
三重解引用:
**&array == array[0][0] 首行首元素的值
怎样定义指针变量存储上述用数组名表示的指针呢?
声明指向多维数组的指针
(1)针对元素地址:array[0]与&array[0][0]
定义:
int * b;
b = array[0];
b = &array[0][0];
(2)针对行地址:&array[0]与array
定义:
int (* c)[n];
c = &array[0];
c = array;
(3)针对数组地址:&array
定义:
int (* d)[m][n];
d = &array;
在地址后面的[]中增加会出现什么情况?类似[0]到[2]
(1)针对元素地址
&array[0][0] 变为 &array[0+row][0+col],地址增加row×n + col个存储单元
array[0] 变为 array[0 + num] ,地址增加 num×n个存储单元,但是array[0 + num]还是元素地址,+1的步长不变,步长为:1个存储单元。注意:array[0] + 1与array[0 + 1]不同。
(2)针对行地址
&array[0] 变为 &array[0 + num],地址增加 num×n个存储单元,&array[0 + num]还是行地址,+1的步长不变,步长为:n个存储单元。这里与(1)中不同的是:
&array[0 + num] == &array[0] + num 的值相同。
总结:二维数组的地址
&array(数组地址),&array[0](行地址),&array[0][0](元素地址)
另外两个特殊的:
array(行地址),array[0](元素地址)