作者 whispar
专栏 : C语言从无到有
✨放低姿态,空杯心态✨
目录
指针(进阶)--笔试题剖析
笔试题一
笔试题二
笔试题三
笔试题四
笔试题五
笔试题六
笔试题七
指针(进阶)--笔试题剖析 笔试题一
✅程序的结果是什么?
#includeint main() { int a[5] = { 1, 2, 3, 4, 5 }; int *ptr = (int *)(&a + 1); printf( "%d,%d", *(a + 1), *(ptr - 1)); return 0; }
笔试题二详解:&a取出的是整个数组的地址 ,&a+1表示增加了一整个数组的大小,单位是字节
数组名a为首元素的地址&a[0],则*(a+1)即 a[1] 的值
故答案为2 5
#includeint main() { int a[4] = { 1, 2, 3, 4 }; int *ptr1 = (int *)(&a + 1); int *ptr2 = (int *)((int)a + 1); printf( "%x,%x", ptr1[-1], *ptr2); return 0; }
笔试题三详解:
&a取出的是整个数组的地址 ,&a+1表示增加了一整个数组的大小,单位是字节
ptr1[-1] = ptr1 -1 , 由图可知 ,(int *)(&a + 1) 在内存中指向的是 04 00 00 00
使用%x打印即 00 00 00 04, 故 ptr1[-1] = 4
由上图可知,(int*)((int)a+1) 在内存中指向的是 00 00 00 02
在小端存储模式下用十六进制表示,即 02 00 00 00
使用%x打印即 2 00 00 00, 故*ptr2 = 2 00 00 00
#includeint main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int *p; p = a[0]; printf( "%d", p[0]); return 0; }
详解:
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
// = {1,3,5}
// 1 3 a[0] 即第一行的数组名 ,p= a[0]则p[0] = a[0][0] = 1
// 5 0
// 0 0
笔试题四
#includeint main() { int a[5][5]; int(*p)[4]; p = a; printf( "%p,%dn", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]); return 0; }
详解:
&p[4] [2] - &a[4] [2] 指针相减得到元素个数,为4个,又低地址-高地址,%d打印结果为 -4
使用%p打印时,打印-4地址
原码10000000 00000000 00000000 0000 0100
反码11111111 11111111 11111111 11111011
补码11111111 11111111 11111111 11111100
即FF FF FF FC
笔试题五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 表示的是首元素的地址
#includeint main() { char *a[] = {"work","at","alibaba"}; char**pa = a; pa++; printf("%sn", *pa); return 0; }
笔试题七详解: char* a[] 为一个存放字符串地址的数组,其中a 表示字符串”work“首元素的地址, 赋值给了pa
pa++时,向前移动一个char*的大小,即指向字符串”at'' 的首元素的地址,故 *pa = "at";
int main()
{
char *c[] = {"ENTER","NEW","POINT","FIRST"};
char**cp[] = {c+3,c+2,c+1,c};
char***cpp = cp;
printf("%sn", **++cpp);
printf("%sn", *--*++cpp+3);
printf("%sn", *cpp[-2]+3);
printf("%sn", cpp[-1][-1]+1);
return 0;
}
详解:如下示
#include#include int main() { char* c[] = {"ANTER","NEW","POINT","FIRST"}; char** cp[] = {c + 3,c + 2,c + 1,c}; char*** cpp = cp; printf("%sn",**++cpp);//POINT //cpp+1指向c+2,两次解引用后找到POINT printf("%sn", *--*++cpp + 3);//ER //++cpp:cpp指向c+1 //*(++cpp):得到c指针数组的第二个元素的指针的内容 //--(*(++cpp)):第二个元素指针-1,得到第一个元素指针的内容 //*(--(*(++cpp))):解引用得到ENTER //*(--(*(++cpp)))+3:指向E,输出ER printf("%sn",*cpp[-2]+3);//ST //注意cpp到目前为止还是指向c+1,cpp[-2]指向的地址内容变化,cpp的指向并未变化 //*cpp[-2]==*(*(cpp+(-2))) 所以*cpp[-2]指向,c+3,得到的是FIRST //*cpp[-2]+3指向S printf("%sn",cpp[-1][-1]+1);//EW //注意cpp到目前为止还是指向c+1 //cpp[-1][-1]+1 == *(*(cpp-1)-1)+1 //*(cpp-1)指向c+2; //*(*(cpp-1)-1)指向c[2]的内容; //*(*(cpp-1)-1)+1指向NEW中的N return 0; }
如果文章对你有帮助,请多多点赞、收藏、评论、关注支持!!



