指针笔试题1

指针类型笔试题1

	int a[5] = { 1, 2, 3, 4, 5 };
	int *ptr = (int *)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));

*(a+1)代表的是:a的首元素地址 +1 然后进行解引用得到的数按十进制打印

指针 ptr 对数组名进行取地址,然后加1,则指针指向了5的下一位,但是打印的时候下标减1,则又回到了5的地址,解引用后是5;

指针类型笔试题2

	struct Test//大小为:20
	{
		int Num;
		char *pcName;
		short sDate;
		char cha[2];
		short sBa[4];
	}*p;
	p = NULL;
	printf("%p\n", p+0x1);//00 00 00 14
	printf("%p\n", (unsigned long)p + 0x1);//00 00 00 01
	printf("%p\n", (unsigned int*)p + 0x1);//00 00 00 04

首先 p+0x1 ==0x___?
指针加1跳过一个元素,一个元素占20个字节(结构体大小)20按十六进制是:14

然后把 p+0x1 外加一个(unsigned long)类型,强制转换为无符号长整形,
再加1,结果就是1;(p指针指向空相当于0)按十六进制打印就是0x00000001

p+0x1外加一个 (unsigned int*)类型,转换为指针,类型是 int 型,所以占4个字节
跳过4个字节,按十六进制打印就是0x00000004;

指针类型笔试题3

	int a[4] = { 1, 2, 3, 4 };
	int *ptr1 = (int *)(&a + 1);
	int *ptr2 = (int *)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);

第一个ptr1[-1] 和上面一样,打印的是4;
第二个要看计算机是大端序还是小端序,如果是小段序则是下面这种:
指针笔试题1

小端字节序:数据的高位存储在高地址上,低位存储在低地址上(如下图)
指针笔试题1
大端字节序:数据的高位存储在低地址上,低位存储在高地址上
指针笔试题1
问:如果这台机器是大端字节序,则答案是?

指针笔试题1

指针类型笔试题4

	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	int *p;
	p = a[0];
	printf("%d", p[0]);

二 维数组可以看成 一维数组,指针 p 指向 a 的第一个元素;
如果你想的是0,那就掉坑了,数组的元素排列是:
1 3
5 0
0 0
因为(A,B)是逗号表达式,只取后一个数字;

指针类型笔试题5

	int a[5][5];
	int(*p)[4];
	p = a;
	printf("a_ptr=%#p,p_ptr=%#p\n", &a[4][2], &p[4][2]);
	printf("%p,%d\n", &a[4][2] - &p[4][2], &a[4][2] - &p[4][2]);

int (* )[4] 和 int (*)[5] 数组的下标不同;会出现警告,但c语言容忍了这个错误;
打印结果为
a_ptr=00EFFDD0,p_ptr=00EFFDC0
00000004,4

下面是一张内存简图:

指针笔试题1
这样的话,&a[4][2] - &p[4][2],相差4个地址,也就是16个字节
指针减指针代表的是空的地址,不是字节,所以是 -4

指针类型笔试题6

	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	//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 ));

打印结果为10 , 5
第一个打印结果:给数组名取地址+1后指针指向了数组尾元素的后面,但是在打印的时候指针又减了1,所以指针指向的是数组尾元素;

第二个打印结果:首先可以看成是 一维数组,int *aa[5];
int *aa[0] = {1,6}; int *aa[1] = {2,7};int *aa[2] = {3,8};…
所以给aa指针加一,指向了6的地址;在打印的时候减1,所以指针指向了5的地址

指针类型笔试题7

	char *a[] = { "work","at","alibaba" };
	char**pa = a;
	pa++;
	printf("%s\n", *pa);

这个比较简单吧,二级指针指向了指针数组名,++就是指针的指向加一,指到 at

指针类型笔试题8

	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);

这个题也比较简单,就是比较麻烦~答案是:
POINT
ER
ST
EW

【1】三级指针cpp指向的是二级指针数组,先自加1,得到的是c+2的地址,然后解引用,得到c+2,指向的是POINT这个指针元素的地址,最后再解引用得到POINT

【2】第二步和第一步不能分开来看,因为++cpp后指针指向了c+1的地址,解引用得到c+1这个指针,指向了NEW的地址,自减1后指针指向了ENTER,最后加三代表的是指针往后移三个,最后指向了E,打印的是:ER

【3】cpp[-2]代表的是c + 3这个地址,因为上一个cpp指向的是c + 1;解引用得到FIRST这个地址,指针指向的是F这个元素,加三,指针后移三位指向S

【4】由第二个cpp指向的是c + 1,cpp[-1][0]代表的是:c + 2,指向的是POINT;cpp[-1][-1]代表的是NEW这个地址;

指针笔试题1
指针题好难吧,不过再难多看几遍也就会了(偷笑)