数组和指针面试题的补充(细的抠jio)

生命是一条艰险的峡谷,只有勇敢的人才能通过。           ——米歇潘

说明:用的vs都是x86的环境,也就是32位平台。

建议:对于难题来说,一定要配合画图来解决问题。

第一题:

#include<stdio.h>
int main()
{
	int a[4] = { 1,2,3,4 };
	int* ptr1 = (int*)(&a + 1);
	//&a表示取出整个数组的地址,&a+1也就跳过了一个数组
	//此时ptr1也就是4后面一个数的地址
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	//ptr1[-1]表示为*(ptr1-1),ptr1-1就表示数组的最后一个数的地址
	//*(ptr1-1)也就是4
	return 0;
}

int* ptr2 = (int*)((int)a + 1)中,a为地址,但是 (int)a 将a强制转换为整数。

比如:假设a的地址就是0x0012ff40,(int)a将a强制转换为整数0012ff40,+1之后就变成了0012ff41。与之前的a的地址比较,就变了1,故相当于加上了一个字节。

又因为最后是以%x打印出来的,4的十六进制就是4,最后打印出来就是4。

而0x02000000以%x打印出来就是2000000,最后结果就是2000000。


第二题: 

int main()
{
	int a[3][2] = { (0,1),(2,3),(4,5)};
	int* p;
	p = a[0];
	//a[0]表示第一行的数组名,而数组名表示首元素的地址
	//a[0]就相当于&arr[0][0]
	printf("%d\n", p[0]);
	//p[0]表示为*(p+0),最后也就是a[0][0]的值,也就是0
	return 0;
}

答案为什么是1呢?刚刚我们分析的没有问题呀,确实刚刚我们分析的是没有问题的。

 但是仔细看看你会发现,二维数组里面是括号,而不是花括号。int a[3][2] = { (0,1),(2,3),(4,5)}。

这样的话二维数组里面就是三个逗号表达式呀,而逗号表达式的结果就是最后一个值得结果。二维数组最后结果就是int a[3][2] ={1,3,5}。所以a[0][0]也就是1了呀

此题给我们一个教训:在做题时一定要认真的看题,注意细节,方可立于不败之地。


第三题:

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]);
	//指针减指针是中间的数字个数。
    //p解引用访问4个整型
	return 0;
}

可以看出中间元素是4个,但是是低地址减搞地址,所以以%d打印出来的结果是-4

-4的原码:10000000000000000000000000000100

  反码:     111111111111111111111111111111111011

  补码:     111111111111111111111111111111111100

%p打印出来的是十六进制的数,所以-4的补码转换为16进制为:FFFFFFFC

所以最后的结果是:FFFFFFFC,-4。


第四题: 

int main()
{

	int aa[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
	int* ptr1 = (int*)(&aa + 1);
	//&aa取出整个数组的地址,&aa+1跳过整个数组

	int* ptr2 = (int*)(*(aa + 1));
	//aa表示第一行的地址,aa+1之后就是第二行的地址
	//也就是&a[1],解引用就变成了a[1]
	//而a[1]是第二行的数组名,而数组名表示数组首元素的地址

	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	//(ptr1 - 1)表示数组最后一个数组的地址,解引之后就是10
	//(ptr2 - 1)也就是表示5的地址了
	return 0;
}


第五题: 

int main()
{
	char* a[] = { "hello","world","quick" };//这是一个指针数组
	char** pa = a;//pa表示首元素的地址
	pa++;//指向下一个地址
	printf("%s\n", *pa);
	//这时pa就表示&a[1],*pa就是a[1]
	return 0;
}


第六题:

好,最难的来了,我们还是一样,慢慢分析。

int main()
{
	char* c[] = { "PAPER","BIT","POWER","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;
}

 

感谢支持! 

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值