指针和数组相关的练习题。

前几天学完了指针,今天就来做一些经典的题来巩固自己的知识。

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。

这就是我所准备的题,如果大家把这些都掌握了,那就说明大家的指针学的很好,欢迎大家来学习。






猜你喜欢

转载自blog.csdn.net/ymk1507050118/article/details/80421599