下面这个例子希望能进一步帮助大家理解 * 在多维数组里的一个应用
利用 * 来得到数组中某个元素的地址 和相对应值
#include<stdio.h>
#define pr printf
int main(void)
{
int a[10][10] = { 0 };
a[2][1] = 666;
pr("证明*a+2=&a[0][2]\n");
printf(" *a+2=%p\n", *a+2);
printf("&a[0][2]=%p\n\n",&a[0][2]);
pr("证明*(a+2)=&a[2][0]=a+2=&a[0]+2\n");
printf(" *(a+2)=%p\n", *(a + 2));
printf(" a+2 =%p\n", a + 2);
printf(" &a[0]+2=%p\n", &a[0] + 2);
printf("&a[2][0]=%p\n\n", &a[2][0]);
pr("证明*(a+2)+1=&a[2][1]\n");
printf("*(a+2)+1=%p\n", *(a + 2) + 1);
printf("&a[2][1]=%p\n\n", &a[2][1]);
printf("%d\n", a[2][1]);
printf("%d", *(*(a + 2) + 1));
return 0;
}
运行结果如下:
通过上述例子,我们可以得出:对于一个多维整型数组(以代码中的a[10][10]为例)
a(数组名)=数组首元素地址;
a+k=&a[ 0 ]+k; 即 a+k=&a[ k ][ 0 ]
*(a+k)= a+k = &a[ 0 ]+k = &a[ k ][ 0 ]
(a+k)+m=&a[ k ][ m ]
( (a + k) + m)=a[ k ] [ m ]
这结果可能有点拗口,看看另外一位博主总结的:
文章入口
“
二维数组a[i][j]的数组名a前加上使行地址转换为列地址;
例:
a+i为第i行行地址,则(a+i)为第i行第0列的列地址;
* (a+i)+j为第i行第j列的列地址;
* ( * (a+i)+j)中的第一个是指向运算符,指向第i行第j列所在单元,等价于a[i][j];
”
另外的一点说明:
对于数组a[ i ],a是一个指向整型变量的指针,在这里可以看作它的值为组首元素地址,&a表示一个指向有i个整型变量的数组的指针,因此&a + 1可看作它“跨过”了整个a数组所有元素的地址,如图:
#include<stdio.h>
int main()
{
int a[5] = { 1, 2, 3, 4 ,5 };char b[5] = "1234";
printf("%p\n", a);
printf("%p\n", &a);
printf("%p\n", &a + 1 );
printf("%p\n", b);
printf("%p\n", &b + 1);
//printf("&a+1 = %d\n", &a + 1);
return 0;
}
运行结果为:
000000BA7B6FFC58
000000BA7B6FFC58
000000BA7B6FFC6C
000000BA7B6FFC84
000000BA7B6FFC89
从这里我们可以看出,在不同类型指针后面+1,“跨过”的位数不同,由指针所指向的元素所占内存空间决定:
对&a,&a+1=&a+1×5(数组里共有5个整型变量)×4(每个int整型变量占4个字节);
而对&b,&b+1=&b+1×5(数组里共有5个字符)×1(每个字符占1个字节);
对整型数组a而言,a + 1 =&a[ 0 ]+4(一个整型变量占据的内存);