首先简单来讲,指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。下面将进行详细介绍。
(以二维数组为例)
int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};
1.1
a是数组名,a数组包括3行3列,可以理解为有三个行元素,而且每个行元素又是一个一维数组,其实数组在内存中真实存在的状态是连续的,并不分行列,但为了我们更好的理解,才想象成了有行有列的。即二维数组是由一维数组组成的,如 a数组是由3个一维数组组成的。
1.2
还是以上面为例,a代表二维数组首元素地址(首行)起始地址,那么 a+1代表什么呢?
a+1 其实代表第二行首元素地址,也就是a[1] 的地址。这里的加一是表示越过这一行的地址。如果说 a 的地址为1000,则 a+1 的地址为1000+4*3=1012 (第0行有3个整形数据)。
以此类推:a+2 也就是a[2] 的地址也就是1000+4*6=1024
那么第0行第1列的元素地址如何来表示呢?
因为从上可得知,a[0]是一维数组名,所以一维数组名+1不就是该一维数组中第一个元素么。这里的加一是表示越过这一个数据的地址,写为a[0]+1 地址值也就是 1000+4=1004 (1个整形据)。
以此类推:a[0]+0 , a[0]+1 , a[0]+2 等就代表着 a[0][0] , a[0][1] , a[0][2] 的元素地址。
如下表所示:
表示形式 | 含义 | 值 |
---|---|---|
a | 二维数组名,即首元素地址(0行起始地址) | 2000 |
a[0] *(a+0) *a | 第0行第0列元素地址 | 2000 |
a+1 &a[1] | 第1行元素起始地址 | 2012 |
a[1] *(a+1) | 第1行第0列元素a[1][0]地址 | 2012 |
a[1]+2 *(a+1)+2 &a[1][2] | 第1行第2列元素a[1][2]地址 | 2020 |
*(a[1]+2) *(*(a+1)+2) a[1][2] | 第1行第2列元素a[1][2]值 | 元素值 |
总结:记住最重要的一点 a[i] 与 *(a+i)是一样的。
如:
#include <stdio.h>
int main()
{
int a[3][3] = { 1,2,3,4,5,6,7,8,9 };
int* p;
p = a[0];
for (p; p < a[0] + 9; p++)
{
printf("%5d", *p);
if( p[0] % 3 == 0)
printf("\n");
}
return 0;
}
结果:
1 2 3
4 5 6
7 8 9
D:\VS\Project4\x64\Debug\Project4.exe (进程 1240)已退出,代码为 0。
按任意键关闭此窗口. . .
分析:
p是一个指针变量,类型为 int * 型,其可以指向一般的整型变量,也可以指向整形的数组元素。
通过指针的方式将二维数组的值来依次输出。(用指向元素的指针变量输出二维数组各元素值)。
作用:用指针变量作形参,用来接受实参数组名传递来的地址。
如:
#include <stdio.h>
void test(int* p)
{
int* a = p;
for (p; p < a+ 9; p++)
{
printf("%5d", *p);
if (p[0] % 3 == 0)
printf("\n");
}
}
int main()
{
int a[3][3] = { 1,2,3,4,5,6,7,8,9 };
int* p;
p = a[0];
test(p);
return 0;
}
结果:
1 2 3
4 5 6
7 8 9
D:\VS\Project4\x64\Debug\Project4.exe (进程 13920)已退出,代码为 0。
按任意键关闭此窗口. . .
分析:当p作为实参进行传递时,一定要保证形参的类型与实参类型一致。
用此种方法一样可以打印出来。(指向指针变量的指针变量)诠释了指向数组的指针作为函数参数。