网络知识 娱乐 图解八道经典指针笔试题

图解八道经典指针笔试题

题目目录

  • 第一题
  • 第二题
  • 第三题
  • 第四题
  • 第五题
  • 第六题
  • 第七题
  • 第八题

第一题

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0; }
//程序的结果是什么?

a与ptr的内存图:

在这里插入图片描述
a + 1和 ptr - 1:

在这里插入图片描述
解引用后答案为:

2,5


第二题

struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p = 0x100000;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
int main()
{
	printf("%pn", p + 0x1);
	printf("%pn", (unsigned long)p + 0x1);
	printf("%pn", (unsigned int*)p + 0x1);
	return 0;
}

本题涉及结构体大小的计算,有遗忘的小伙伴可以看一看:结构体/联合体大小的计算
此结构体的大小为20字节

这道题首先要知道指针加整数要看指针类型,而整数加整数就可以直接加
p+0x1 就是跳过一个p类型大小,就相当于+20
(unsigned long)p + 0x1 俩整数相加,直接加
(unsigned int*)p + 0x1 跳过p类型大小,相当于+4

最后答案为:

0x100020
0x100001
0x100004


第三题

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);
    return 0; 
}

ptr1跟第一题一样,要注意的是ptr2,(int)a + 1中的+1是加一个字节,而一个整形有四个字节,a是首元素地址,(int)a + 1后:
在这里插入图片描述
而因为ptr2是int* 类型,所以解引用时要向后看四个字节:
在这里插入图片描述
小端存储取出来后就为02 00 00 00
最后的答案为:

4, 2000000(16进制不打印前面的0)


第四题

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

这里有个陷阱:逗号表达式
真正的内存图:
在这里插入图片描述

最后的答案为:

1


第五题

int 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; 
}

a[4][2]很好找,但是p[4][2]不好找,p指针的类型是int(*)[4]p[4][2]可以看做:
在这里插入图片描述
&p[4][2] - &a[4][2]结果是-4
在这里插入图片描述
所以答案为:

FF FF FF FC , -4


第六题

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

在这里插入图片描述
答案:

10, 5


第七题

int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%sn", *pa);
	return 0;
}

在这里插入图片描述
pa++后指向的a指向"at"
答案为:

“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;
}

先把图画出来
在这里插入图片描述
因为打印函数中存在++和- -,会改变下一步的结果,所以要一步步分析
1️⃣**++cpp
在这里插入图片描述
指向的是"POINT"

2️⃣*-- * ++cpp + 3
①++cpp
在这里插入图片描述
②-- * ++cpp
在这里插入图片描述
③*-- * ++cpp + 3
在这里插入图片描述
指向的为"ER"
3️⃣*cpp[-2] + 3
在这里插入图片描述

在这里插入图片描述指向的为"ST"
4️⃣cpp[-1][-1] + 1

①cpp[-1]
在这里插入图片描述
②cpp[-1][-1]
在这里插入图片描述
③cpp[-1][-1] + 1
在这里插入图片描述
指向的为"EW"
所以答案为:

POINT
ER
ST
EW