指针运算笔试题解析

2023-12-17 11:49:17

题目一

#include <stdio.h>
 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代表的是数组首元素的地址,a+1代表的是2的地址,2解引用就是2,所以答案是2

第二个当中,答案是5,首先,我们知道&a代表的是整个数组的地址,&a+1则是跳过了这个数组,然后转化为int*类型,存放到了ptr当中。

ptr-1代表着此时原本在数组末尾的地址向前移动了一步,此时代表的是5的地址,然后解引用,代表的就是5.

题目二

 //在X86环境下

//假设结构体的??是20个字节

//程序输出的结构是啥?
#include<stdio.h>
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p = (struct Test*)0x100000;
int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

看到这个答案,大家知道原因吗?此时编译器为x86环境,这是因为最初的机器基本都是x86环境

首先,我们知道p是0x100000,而p+1跳过的是一个结构体大小,这个机构体是20个字节,所以可能有好多同学觉得答案是0x100020,但是这个是16进制啊,所以答案应该是00100014

第二个的答案是00100001,这个是因为首先p进行了类型的强制转换,从结构体类型转换成了整数类型,整数类型+1,那真的是+1,所以答案是00100001,

第三个答案是是00100004,有了上面的那个例子,这个例子是不是就很好理解,因为此时的p被强制类型转换成了指针类型,指针类型的大小是4/8,此时是x86环境下,所以指针的大小是4,所以答案是00100004

题目三

#include <stdio.h>
 int main()
 {
 int a[3][2] = { (0, 1), (2, 3), (4, 5) };
 int *p;
 p = a[0];
 printf( "%d", p[0]);
 return 0;
 }

?

这个答案,大家有想到吗?,首先,a数组的这个部分大家看懂了吗

这个是你们认为的a数组,然后设立了一个整数指针p,将a的首行的地址存放到了p当中,然后将p的首元素打印出来,答案是1,这个时候你可能好奇了,答案应该是0呀,怎么会是1呢,别着急,听我慢慢和你说。

首先,a数组就不是上面表现的那样的,(0,1)这个是一个逗号表达式,输出结果是1

所以上面的第一个式子其实等价于下面的这个式子

int a[3][2] = { 1,3,5 };
?

这个搞懂的话,后面的顺其自然自然也懂了。

题目四

//假设环境是x86环境,程序输出的结果是啥?
 
#include <stdio.h>
 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个整数类型的元素,a是一个五行五列的数组

然后将a的地址给了p,所以此时p是数组首元素的地址,而指针-指针的绝对值=二者之间相差的元素个数而p【0】,p【1】,还是p【4】只能包含4个元素,而a【0】,a【2】等能包含5个元,所以&p【4】【2】-&a【4】【2】的结果应该是-4,因为是小地址-大地址,所以用%d打印的时候,打印出来的结果就是-4,当用%p打印的时候,打印的应该是-4的补码(把补码当成了-4的地址,打印出来),结果就是FFFFFFFC

题目五

#include <stdio.h>
 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;
 }

?

有了上面的几道题的经验之后,这道题大家有想法吗?

这里面有两个关键点,首先第一个是&aa+1,这个是跳过了整个数组,此时ptr1指向了aa数组的末尾,第二个是aa+1,这个时候aa是数组名,代表的是数组首元素的地址,也就是aa数组第一行的地址,+1就是指向了第一行元素的末尾,第二行的开始,所以答案第一个是10,第二个是5

题目六

#include <stdio.h>
 int main()
 {
 char *a[] = {"work","at","alibaba"};
 char**pa = a;
 pa++;
 printf("%s\n", *pa);
 return 0;
 }

?

?在这道题当中,首先创建了一个数组a,a当中的每个元素都是char*类型的指针,下一步当中,把创建了一个指针pa,来存放a的地址,而a的类型是char*,而后pa++,此时pa,指向的是at的地址,然后将pa解引用,打印出来,结果就是at。

文章来源:https://blog.csdn.net/in_seattle/article/details/135017447
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。