前言:本文章将带你刷8道比较有意思的指针笔试题,笔者将由深入浅出解析这些题目!必要的题目,作者已经加上内存布局图!希望本文对你有所帮助! 目录 一.笔试题1 -指针与一维数组的关系-值int main() { int a[5] = { 1, 2, 3, 4, 5 }; int *ptr = (int *)(&a + 1);//&a:取出整个数组的地址,&a+1:跳过一个数组 //&a的类型为:数组指针 int(*)[5] 所以要强转 //a为数组名,首元素地址,即为1的地址,+1,跳过一个元素,即为2的地址 printf( "%d,%d", *(a + 1), *(ptr - 1)); // 2 5 return 0; } 图解: 二.笔试题2-指针与结构体//这里告知结构体的大小是20个字节 struct Test { int Num; char *pcName; short sDate; char cha[2]; short sBa[4]; }*p; //假设p 的值为0x100000。 如下表表达式的值分别为多少? int main() { p = 0x00100000; //0x1-->对应的值就是1 相当于0x00000001 printf("%p\n", p + 0x1);//p为结构体指针,指向一个结构体,+1,跳过一个结构体,即跳过20个字节, // 0x00100000+20 -> 0x00100020 错误, 要将20转化为16进制再加,或者将16进制0x00100000转化为10进制之后加上20,然后再转化为16进制 // 20-> 0X00000014 //所以最终结果为:0x00100014 printf("%p\n", (unsigned long)p + 0x1);//将p转化为长整形,+1,即为整形+1, 例如:500+1= 501, //所以结果为: 0x00100001 printf("%p\n", (unsigned int*)p + 0x1); //将p强转为无符号整形,+1跳过一个整形->跳过4个字节 //所以结果为:0x00100004 return 0; } 注意坑点:整数+1 ->跳过一个字节 执行普通的加减运算 而整形指针+1 ->跳过四个字节 指针+1 的步长取决于指针指向的数据的类型 三.笔试题3-指针与一维数组的关系-址int 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);// 4 2000000 return 0; }
图解: 注意点:整形+1:加一个字节 如:500+1 = 501 整形指针+1:跳过(加)4个字节 四.笔试题4-指针与逗号表达式int main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int *p; p = a[0]; printf("%d ",p[0]);//1 return 0; } 坑点:逗号表达式-结果为最后一个表达式的结果 图解: 所以相当于只初始化了前三个元素,后面的元素未初始化,默认为0
五.笔试题5-指针与二维数组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) 图解: &p[4][2]为小地址,&a[4][2]为大地址,小地址减大地址,所以最后结果为-4
使用%p方式打印:打印的是-4对应的补码 1111 1111 1111 1111 1111 1111 1111 1100 ->结果为:FFFFFFFC 整数在内存中以补码方式存储,打印地址和打印无符号整数一样,都是打印内存中补码 使用%d方式打印:打印二进制补码对应的原码,=> -4 注意:a是二维数组,对应数组指针的类型为:int(*)[5],指向的是有5个元素的一维数组 而p是数组指针,指向的数组只有4个元素,所以会有警告 ->可以写成 int(*p)[4] = (int(*)[4])a 消除警告 六.笔试题6-指针与二维数组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)); // 5 10 return 0; }
图解: 七.笔试题7-指针与字符指针数组#includeint main() { char *a[] = {"work","at","alibaba"}; char**pa = a; pa++; printf("%s\n", *pa); return 0; }
图解: 八.笔试题9-指针与字符指针数组(难)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; } 这道题比较难,所以我们分表达式解决! 最最最初的内存布局:
总结: 能坚持看完,你已经比别人优秀很多了!也感谢你看到最后,如果笔者哪里写错了的话,欢迎大佬们评论区指正!如果此文对你有帮助的话,欢迎留个关注,留个赞再走呀! |
|