五六题
五
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; }
输出的结果是什么?
分析:首先定义了一个二维数组a,有定义了一个数组指针要十分的注意这个数组指针指向的数组看作是4个元素的。
p这个指针变量存放的a,a又代表着二维数组数组第一行的地址。
- &p[4][2]:&* ( *(p+4)+2),p的类型是数组指针+4只能跳过4个元素的数组,这里一行是5个元素所以跳不完,+4最后在倒数第二行停下,再+2,得到这一行第四个元素的地址,再解引用,由于二维数组没有初始化就得到0。再取出这个元素的地址。
- &a[4][2]:就是取出最后一行第三个元素的地址。
&p[4][2] - &a[4][2]:是小地址减去大地址,因为数组随下标的增长地址有低变高。地址相减就相当于指针相减,因为地址就是指针,所以根据指针相减得到的是指针之间的元素个数得到最后结果是4。
图:
六
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", *(ptr1 - 1), *(ptr2 - 1)); return 0; }
输出的结果是什么?
分析:aa是个二维数组的两行一共十个元素。
&aa + 1:aa是二维数组数组名对二维数组的数组名取地址就是拿到整个数组的地址,整个数组的地址+1,就跳过整个二维数组。
*(aa + 1):可以写成这样aa[1],相当于第一行的地址+1再解引用得到第二行的地址,aa[1]也就相当于数组名。
图
七八题
七
int main() { char* a[] = { "work","at","alibaba" }; char** pa = a; pa++; printf("%s\n", *pa); return 0; }
输出的结果是什么?
分析:有一个字符指针数组,里面有三个元素,又有一个二级指针存储a的首元素的地址,因为a的首元素是char *类型存储的是字符串的首字符地址。pa++就意味着pa中存储的地址+1,就到了数组的下一个元素,下一个元素是’‘at’'的首字符地址,故输出的是at。
八
这一题也是最难的一题
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; }
输出的结果是什么?
分析:有一个字符指针数组。数组的每个元素是相应字符串的首字符地址。
而cp这个二级指针数组存放的是char *类型的地址,刚好c数组的每个元素是char *,最后cpp这个三级指针指向的是二级指针数组的首元素地址。
- 图
printf("%s\n", **++cpp);
,首先cpp先永久+1,也就是移动char ***个步长也就是1,得到指向c+2地址处,再解引用得到c+2,而c+2是c这个数组中的地址,再解引用得到"POINT"。
-*-- * ++cpp + 3
:首先我们还是要明确理解的顺序,先cpp永久+1,再解引用,得到c+1,而c+1是c数组中的地址,然后再–,所以改变了c+1的值变成了c,然后再解引用得到"E"的地址,然后再加3,这时候就代表着"ENTER"这个字符串加3,ENTER我们可以理解成就是E的地址再+3,结果就得到"ER"。
就相当于:
int main() { printf("%s", "abcde" + 3); }
- 图
*cpp[-2] + 3
:首先我们拆解一下,* (*(cpp-2))+3,首先cpp-2,但是不是永久的,然后再解引用,上面我们cpp指向的是下标为2的位置,现在应该指向0,解引用得到c+3,再解引用得到F的地址,F的地址+3得到"ST";
cpp[-1][-1] + 1
:首先还是拆解一下,* (*(cpp-1)-1)+1,cpp-1指向c+2,解引用得到c+2,c+2然后要-1得到c+1,c+1解引用得到"NEW",再+1输出"EW"。
总结😈
这篇博客篇幅较长是因为先要深入的理解数组与地址与指针的关系是不太容易的,所以我们需要题目来练习,在数组方面我们让大家理解了数组名±或者&的一些差异,也包括一些类型的不同,指针方面也比较全面是各种类型的杂糅为的就是锻炼自己的理解能力。 完(๑′ᴗ‵๑)