int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1);
int* ptr2 = (int*)(*(aa + 1));
printf("%d,%d\n", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
aa的布局是12345 678910。
ptr1,取出整个数组的地址+1,也就指向了10后面。
ptr2,aa是首元素地址,也就是第一行地址,+1,也就是第二行地址,解引用,就拿到了第二行,此时也就是数组名,也就是第二行第一个元素6.*(aa + 1),之前学过,其实就是aa[1]。
那么两个结果就是10和5.
int main()
{
char* a[] = { "work", "at", "alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
指针指向字符串时,指向的是第一个字符的地址。
a的布局,三个char*类型的字符串,现在char**pa指向a的首元素地址,也就是“work”的w的地址,现在pa++,跳过一个char*的字符串,所以就是“at”中的a的地址,这样以%s打印出来后就是at。
int main()
{
char* c[] = { "ENTER", "NEW", "POINIT", "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;
}
把这三个字符指针全都列出来
cpp cp c
char*** c+3 ENTER
c+2 NEW
c+1 POINT
c FIRST
现在cpp指向cp首元素地址,也就是c+3.c是数组名,也就是首元素地址,对应着ENTER,那么c+1——NEW, c+2——POINT, c+3——FIRST.现在看printf里面的内容。
第一个,**++cpp,cpp指向c+3,先++,那么cpp就指向了c+2,然后*++cpp,得到的就是c+2里面的内容,c+2存储着POINT的地址,再次解引用,**++cpp,得到的就是POINT。
第二个,此时cpp已经指向c+2了。
先++,指向c+1,然后解引用,得到c+1的内容,此时c+1需要--,也就变成了c,c解引用后得到其中的内容ENTER中的首元素E,+3,也就得到了ER。
第三个,cpp此时指向c+1,*cpp[-2] + 3,也就相当于*(*(cpp - 2)) + 3。
cpp-2,也就变成c+3,双次解引用,得到FIRST首元素F,+3,得到ST。
第四个,也就是*(*(cpp-1)-1)+1。
cpp还是c+1,-1后就变成c+2,解引用得到c+2的内容,POINT的地址,然后-1,也就指向了c+1所指向的内容NEW,再次解引用得到N,+1,最终得到EW。
结束。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)