前几天学完了指针,今天就来做一些经典的题来巩固自己的知识。
1.
int main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); printf("%d,%d",*(a+1),*(ptr-1)); return 0; }
解析:首先这道题答案是2,5.因为首先它先定义一个数组,然后定义一个指针变量指向下一个数组。a+1表示对第二个元素的地址,在解引用表示第二个元素,所以第一个答案是2。 (&a+1)表示下一个数组的地址也就是ptr,所以ptr-1就是最后一个元素的地址,在解引用就是最后一个元素5。
2.
struct Test { int Num; char *pcName; short sDate; char cha[2]; short sBa[4]; }*p; p=0x100000 (1)p+0x1=0x100014; (2)(unsigned long)p+0x1=0x100001; (3)(unsigned int*)p+0x1=0x100004;
解析:首先这是一个结构体,而它的大小为(4+4+2+1*2+2*4)=20。然后第一问,p+1就是给p所指向类型+1,所以是加20,十六进制中20就是14,所以答案是0x100014。第二问因为将p强转成长整型所以+1就是+1,答案是0x100001。第三问因为强转成了int *型,所以+1就是+4,答案是0x100004。
3.
int main() { int a[4]={1,2,3,4}; int *ptr1=(int *)(&a+1); int *ptr2=(int *)((int)a+1); printf("%x,%x",ptr[-1],*ptr2); return 0; }
解析:首先定义一个有四个元素的数组,在定义一个指针变量ptr1指向(&a+1)也就是下一个数组的地址。在定义一个指针变量ptr2指向((int)a+1)。所以第一个ptr1[-1]也可以写成*(ptr1-1)也就是最后一个元素所以答案是4。第二个*ptr2表示它所指向的值。((int)a+1)就是取4个字节。它一开始指向的是01,后面依次是00 00 00 02 00 00 ...,所以加4就变成了0000002但是因为电脑是小端所以正确的应该是2000000。
4.
#include<stdio.h> #include<Windows.h> int main(int argc,char *argv[]) { int a[3][2]={(0,1),(2,3),(4,5)}; int *p; p=a[0]; printf("%d\n",p[0]); system("pause"); return 0; }解析:因为定义二维数组时用的是逗号表达式,只看括号里后面的数,所以数组元素应为1,3,5,0,0,0.所以p[0]表示第一个元素,所以答案是1。
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][2]可以写成*(*(p+4)+2)表示第四个元素中的第四个元素,而&a[4][2]表示第五个元素的第三个元素,所以两个相差4个字节,但是因为小端所以第二个答案是-4。但是地址是无符号数,所以-4的二进制为:
-4 源码:1000 0000 0000 0000 0000 0000 0000 0100 反码:1111 1111 1111 1111 1111 1111 1111 1011 补码:1111 1111 1111 1111 1111 1111 1111 1100 十六进制:F F F F F F F C
所以第二个答案是FFFFFFFC。
6.
#include<stdio.h> int main() { char *a[]={"work","at","alibaba"}; char**pa=a; pa++; printf("%s\n",*pa); return 0; }
解析:先定义一个指针数组,开辟四个字节的空间,前三个元素分别是那三个单词,然后定义一个二级指针变量pa指向a。pa++因为pa指向第一个元素的地址,在++就指向第二个元素的地址,在解引用就是第二个元素at。
7.注意:此题很经典,如果掌握了就证明你的指针就算学的不错了。
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; }解析:首先画个图表明现在的状态:
红色线第一个先++,在解引用,如图最后指向了POINT。
黄色线。第二个先给cpp++往上走一位,在解引用到*c,在--向上移一位,在解引用到ENTER再加3,结果就是ER。
绿色线。第三个因为cpp本身没变所以是虚线,先进行cpp[-2]就是*(cpp-2)到*c,在解引用到FIRST,在+3到ST。
蓝色线。第四个相当于*(*(cpp-1)-1)+1。先cpp-1往下移一位解引用到cp在-1往上移一位在解引用到NEW,在加1得到EW。
这就是我所准备的题,如果大家把这些都掌握了,那就说明大家的指针学的很好,欢迎大家来学习。