指针运算笔试题解析

题目一

#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。

相关推荐

  1. Spring IoC面试题解

    2023-12-17 16:30:03       39 阅读
  2. 指针运算

    2023-12-17 16:30:03       44 阅读
  3. C语言指针数组 指针运算

    2023-12-17 16:30:03       72 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-17 16:30:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-17 16:30:03       106 阅读
  3. 在Django里面运行非项目文件

    2023-12-17 16:30:03       87 阅读
  4. Python语言-面向对象

    2023-12-17 16:30:03       96 阅读

热门阅读

  1. Harmonyos系统web组件使用

    2023-12-17 16:30:03       53 阅读
  2. css中定位方式

    2023-12-17 16:30:03       64 阅读
  3. ESlint代码规范

    2023-12-17 16:30:03       57 阅读
  4. sql解析,转换列表和表名

    2023-12-17 16:30:03       63 阅读
  5. Debezium发布历史08

    2023-12-17 16:30:03       72 阅读
  6. 从零开始学Python系列课程第15课:range 方法详解

    2023-12-17 16:30:03       55 阅读
  7. 【Linux应用编程笔记】tslib库使用

    2023-12-17 16:30:03       50 阅读
  8. LaTeX入门教程

    2023-12-17 16:30:03       46 阅读
  9. 条款3:尽量使用const

    2023-12-17 16:30:03       58 阅读
  10. Unity触摸 射线穿透UI解决

    2023-12-17 16:30:03       65 阅读