1、
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
//p为数组指针,指向元素个数为4的整形数组,所以下面p[4]=p+4,跳过四个为四个元素的数组,而p[4][2]=*(p+4)+2即以刚刚的基础上在跳过两个元素。同理a[4][2]为二维数组,二维数组的每一行都是一个一维数组作为一个元素,把二维数组看成有四个元素的一维数组。a[4]为第四行首元素地址,而a[4][2]=*(a+4)+2即在刚刚的基础上再跳过两个元素为第四行第三个元素。
//因为进行了&取地址,地址减地址为地址之间的元素个数,而小地址减大地址得到的是负数(-4),而%p打印地址,因为-4以补码形式存储111111111111111111111111111111100,打印地址时直接将补码转换成十六进制FF FF FF FC.
打印FF FF FF FC,-4
2、
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *ptr1 = (int *)(&aa + 1);//取地址加一跳过整个数组,因为这是一个二维数组,所以取地址后的//类型应为数组指针才能放该数组地址。所以&aa+1也为数组指针类型 ,最后ptr1指向跳过数组的位//置
int *ptr2 = (int *)(*(aa + 1));//aa为第一行数组地址加一后为第二行数组地址
printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));//此时为整形指针减一为前移一个字节
return 0;
}
输出10,5
3、
#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};//字符指针数组,字符指针只储存字符首元素地址,然后这些把//这些指针放进数组
char**pa = a;//a为首元素地址放进二级指针pa,因为pa+1是跳过一个char*,所以指向第二个首元素地址
pa++;
printf("%s\n", *pa);
return 0;
}
打印at
4、
int main()
{
char *c[] = {"ENTER","NEW","POINT","FIRST"};
char**cp[] = {c+3,c+2,c+1,c};
char***cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *--*++cpp+3);
printf("%s\n", *cpp[-2]+3);
printf("%s\n", cpp[-1][-1]+1);
return 0;
}