【指针笔试题】

学习了上一期的一些笔试题,这一期我们来看一些关于指针的笔试题:



下面就是一些关于指针的笔试题

笔试题1

来看下面的几行代码,猜测会输出什么结果

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是取出整个数组的地址,+1跳过了整个数组指向,5后面的呢块地址,然后我们把它强制类型转换为int*,然后赋给ptr . *(ptr-1)的意思是,因为此时ptr 的类型是int *,-1向前移动一个字节指向5 的起始地址,然后解引用得到的就是5, *(a+1)a是数组元素名,也是数组首元素,+1并且解引用指向第二个元素。所以打印结果为2 ,5
在这里插入图片描述

笔试题2

来看下面的几行代码,猜测会输出什么结果

//由于还没学习结构体,这里告知结构体的大小是20个字节
struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
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);
 return 0;
}

解析:

p是一个结构体指针,上面代码强调了结构体指针大小是20个字节,这里p+0x1是相当于+20,但是这里要注意是16进制,所以20应该转换为16进制然后在加; p原本是结构体类型的指针,但是这里被强制类型转换为(unsigned long)变成整型了,所以整数+1就是+1; p原本是结构体类型的指针,但是这里被强制类型转换为变成整型指针(unsigned int*)p所以整型指针加1 就是+4.所以打印结果为0x100014 0x100001 0x100004

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

解析:

ptr1[-1]—>*(ptr1-1),所以这个和第一题类似,只是形式不同。我们具体来分析一下 * ptr2 a是数组名,也是数组首元素地址,我们把它强制类型转换为int,又+1,如果它作为地址的话,它就与起始地址差了一个字节,当我们又把它转换为int * 时我们就要具体分析一下他在内存中是如何存放的,假设我们的机器是小端。画图为例:数据在内存中就是这样存放的因为机器是小端,所以取出来,并按照16进制打印,所以打印结果就是0x4 0x2000000.在这里插入图片描述

笔试题4

来看下面的几行代码,猜测会输出什么结果

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

解析:

这道题,比较简单,但是有一个坑我们需要特别注意,数组初始化时{ (0, 1), (2, 3), (4, 5) ,这里是逗号表达式,只要这个注意到了,这个题做对还是比较简单的,其实数组是以下图的形式存放在 内存中的,这里的p[0]等价于 *(p+0)所以打印结果就是1
在这里插入图片描述

笔试题5

来看下面的几行代码,猜测会输出什么结果

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][2]== * (*(p+4)+2))具体看下面的图:我们之前知道数组随着下标的增长,地址是由低到高的所以 &p[4][2] - &a[4][2],是一个低地址,减一个大地址,而且指针减指针,计算的是之间差的元素个数 ,y以%d的形式打印就是-4,但是以%p的形式打印的就是FFFFFFFC -4 FFFFFFFC. 在这里插入图片描述

笔试题6

来看下面的几行代码,猜测会输出什么结果

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

解析:

我们首先来看一下a数组在内存中的存放,我们是把这三个字符,放到数组中了吗?不是的,我们之前说过字符指针,这其实是把每个字符的起始地址,放到了数组a中。如下图所示:在这里插入图片描述
pa++就指向了然后解引用我们就拿到了首字符a的起始地址,所以%s打印的就是 at

在这里插入图片描述

以上就是一些关于指针的笔试题

🌟Hello world 我们下期见!

  • 31
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@小辉灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值