前言
数组与指针有很密切的联系,常见的结合情况有以下三种:
- 数组指针
- 指针数组
- 二维数组指针
数组指针
数组指针:指向数组的指针。如:
int arr[] = {0,1,2,3,4};
int *p = arr;
//也可写作int *p=&arr[0]
也就是说,p,arr,&arr[0]都是指向数组的开头,即第0个元素的地址。
如果一个指针p指向一个数组arr[]的开头,那么p+i为数组第i个元素的地址,即&arr[i],那么*(p+i)为数组第i个元素的值,即arr[i]。
同理,若指针p指向数组的第n个元素,那么p+i为第n+1个元素的地址;不管 p 指向了数组的第几个元素,p+1 总是指向下一个元素,p-1 也总是指向上一个元素。
下面示例证实了这一点:
#include <stdio.h>
int main(void)
{
int arr[] = {0, 1, 2, 3, 4};
int *p = &arr[3]; //也可以写作 int *p = arr + 3;
printf("%d, %d, %d, %d, %d\n",
*(p-3), *(p-2), *(p-1), *(p), *(p+1) );
return 0;
}
运行结果为:
0, 1, 2, 3, 4
指针数组
指针数组:数组中每个元素都是指针。如:
int a=1,b=2,c=3;
int *arr[3] = {&a,&b,&c};
示例程序:
#include <stdio.h>
int main(void)
{
int a = 1, b = 2, c = 3;
//定义一个指针数组
int *arr[3] = {&a, &b, &c};//也可以不指定长度,直接写作 int *parr[]
//定义一个指向指针数组的指针
int **parr = arr;
printf("%d, %d, %d\n", *arr[0], *arr[1], *arr[2]);
printf("%d, %d, %d\n", **(parr+0), **(parr+1), **(parr+2));
return 0;
}
第一个 printf() 语句中,arr[i] 表示获取第 i 个元素的值,该元素是一个指针,还需要在前面增加一个 * 才能取得它指向的数据,也即 *arr[i] 的形式。
第二个 printf() 语句中,parr+i 表示第 i 个元素的地址, * ( parr + i) 表示获取第 i 个元素的值(该元素是一个指针), ** (parr+i) 表示获取第 i 个元素指向的数据。
指针数组还可以和字符串数组结合使用,请看下面的例子:
#include <stdio.h>
int main(void)
{
char *str[3] =
{
"hello C",
"hello C++",
"hello Java"
};
printf("%s\n%s\n%s\n", str[0], str[1], str[2]);
return 0;
}
运行结果为:
hello C
hello C++
hello Java
二维数组指针
二维数组指针:指向二维数组的指针。如:
int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
int (*p)[4] = a;
a[3][4]表示一个3行4列的二维数组,其所有元素在内存中是连续存储的。
请看如下程序:
#include <stdio.h>
int main(void)
{
int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
int i,j;
for( i = 0; i < 3; i++ )
{
for( j = 0; j < 4; j++ )
{
printf("a[%d][%d]=%d\n", i, j, &a[i][j]);
}
}
return 0;
}
运行结果为:
a[0][0]=6422216
a[0][1]=6422220
a[0][2]=6422224
a[0][3]=6422228
a[1][0]=6422232
a[1][1]=6422236
a[1][2]=6422240
a[1][3]=6422244
a[2][0]=6422248
a[2][1]=6422252
a[2][2]=6422256
a[2][3]=6422260
可见,每个元素的地址都是相差4个字节,即每个连续在内存中是连续存储的。
按照以上定义可归纳出如下4个结论:
(1)p指向数组a的开头,也即第1行;p+1前进一行,指向第2行。
(2)*(p+1)表示取第2行元素(一整行元素)。
(3)*(p+1)+1表示第2行第2个元素的地址。
(4)*(*(p+1)+1)表示第2行第2个元素的值。
综上4点,可得出如下结论:
a+i == p+i
*(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j)== *(*(p+i)+j)
以上就是数组与指针常用的三种结合形式。