8道c指针面试题

以下是阿鲤收集的8道指针方面的面试题,并做了简单的讲解,如果有错误欢迎大家提出,如果大家有看不懂的地方,评论区见哦
1:

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

输出结果:
在这里插入图片描述

解析:

 a代表了数组首元素的地址所以*(a+1) 等于2 ; 这道题中int *ptr = (int *)(&a + 1)中的&a代表了整个数组的地址,给&a+1等同于加了整个数组的长度,所以*(ptr - 1) 等于5。

//
//

2:

struct Test
{
	int Num;
	char *pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
int main()
{
	p = (struct Test*)0x100000;
	printf("%p\n", p + 0x1);
	printf("%p\n",(unsigned long) p + 0x1);
	printf("%p\n",(unsigned int*)p+0x1);
	printf("%p\n", (unsigned char*)p + 0x1);
	printf("%p\n", (unsigned char**)p + 0x1);
	system("pause");
	return 0;
}

输出结果:
在这里插入图片描述
解析:

这道题里的结构体struct Test 的大小为20个字节,故printf("%p\n", p + 0x1)输出为00100014(16进制满16进一);
接下来的printf("%p\n",(unsigned long) p + 0x1)将p强制转化成了unsigned long型,变成了一个数字,所以就,直接加1;
接下来的printf("%p\n",(unsigned int*)p+0x1)将p强制转化成了unsigned int*型,变成了一个指向int型的指针,所以加4;
接下来的printf("%p\n", (unsigned char*)p + 0x1)将p强制转化为了 unsigned char*型,变成了一个指char型的的指针,所以加1;
接下来的printf("%p\n", (unsigned char**)p + 0x1)将p强制转化为了unsigned char**型,变成了一个指向char*类型的指针,所以加4。

//
//

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);
	system("pause");
	return 0;
}

输出结果:
在这里插入图片描述

解析:

   int *ptr1 = (int*)(&a + 1),&a代表整个数组的大小,所以加1,直接加到了数组的最后,所以ptr[-1] = *(ptr - 1) = 4;
    此题牵扯到了数组的存储,数组在运行时会存储到栈里,且由低地址向高地址存储,存储方式如下: 01000000 02000000 03000000 04000000 ([小端存储),而在题中的(int*)((int)a + 1)中的
    (int)a,强制把a从地址转化成了int型的数字,所以加1,就直接加1字节,把a地址的指向从 01000000 加成了 指向00000020,而因为为小端存储,所以以十六进制输出时就直接输出了2000000;

//
//

4:

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

输出结果:
在这里插入图片描述

解析:

这道题的考点是逗号表达式,逗号表达式的执行结果是保留最后一个表达式,所以此二维数组就变成了{{1,3},{5,0},{0,0}};而p = a[0]中,p[0]等于*(*(a+0)+0) == 1。

//
//

5:

int main()
{
	int a[5][5];
	int(*p)[4];
	p = (int(*)[4])a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	system("pause");
	return 0;
}

输出结果:
在描述
解析:

这道题中的考点是	p = (int(*)[4])a 等同于*(*(a+4)+0), 而&p[4][2] 等同于*(*(a+4)+2))
而他的类型是 int(*) [4]所以每次加都是加四列,在加2列最后加到的位置是[3][3] 所以
 &p[4][2] - &a[4][2] = -4(%d输出),当以%p输出时要对-4求反码,补码

//
//

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));
	system("pause");
	return 0;
}

输出结果:
在这里插入图片描述
解析:

(int*)(&aa + 1)是对整个数组加1;
(int*)(*(aa + 1))是对数组的第一行整体加一;

//
//

7:

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

输出结果:
在这里插入图片描述
解析:

pa指向a,a指向数组的地址,所以pa++  =》 a++ 等于 *(a+1)等于 at;

//
//

8:

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);
	system("pause");
	return 0;
}

输出结果:
在这里插入图片描述
解析:

本题里的c指向{ "ENTER","NEW","POINT","FIRST" }的地址,cp指向{ c + 3,c + 2,c + 1,c }的地址,cpp指向cp
所以:

printf("%s\n", **++cpp)里面的   **++cpp 等于   *(*(cpp+1)+0) 等于*(c+2)	所以输出为
POINT
printf("%s\n", *--*++cpp+3`)里面的*--*++cpp+3 是在第一步cpp++的基础上执行的 所以
 *--*++cpp+3 等于 *(--(c+1))+3 等于*c+3 , 所以输出为ER
printf("%s\n", *cpp[-2]+3)此时的cpp也是在前两位的基础上执行的,所以*cpp[-2]+3 等于*(c+3)+3
,所以输出为ST
printf("%s\n", cpp[-1][-1]+1)此时的cpp也是在前三位的基础上执行的,所以cpp[-1][-1]+1等于
*(*(cpp-1)-1)+1 = *(*(c+3 - 1)-1)+1 所以输出为ER
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值