C语言8道大厂指针笔试题——拿捏指针

为了题目的准确性和我们一般学习过程中的习惯,这里所有的题目代码都是在 X86 环境(32 位平台)下运行的。
题目一:

#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;
}
//程序的结果输出什么?

我们先研究 ptr 指针变量里面存储的是什么。&a+1 表示取出整个地址并向后跳跃一个数组类型的大小,也就是指向了数组最后一个元素 5 的后面一块数组类型大小的空间。

但是我们想要把这个地址交给指针变量 ptr 是不行的,因为类型不一样(&a+1 是一个数组指针类型,prt 是一个整形指针类型),所以我们在 (&a+1) 之前 (int*) 来强制类型转换。这样我们搞清楚了 ptr 指针变量里存的是什么。

那么现在来看输出部分。*(a+1) 是比较简单的,a 是首元素地址,a+1 是第二个元素地址,对其解引用得到第二个元素 2 ,这是毋庸置疑的答案。对于 *(ptr-1) ,我们知道 ptr 里面存放的地址位置,并且知道 ptr 是一个整形指针,ptr-1 相当于向前跳跃一个整形类型的大小,即指向数组最后一个元素 5 的位置。对其解引用就能得到元素 5 。
在这里插入图片描述
故最后的输出结果为: 2,5 。
题目二:

#include <stdio.h>
 
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}
//程序最后输出什么?

我们注意观察结构体的定义,定义了一个结构体指针变量 p 。

p+0x1 非常简单,0x1 就是 1,只不过是以十六进制的格式书写的。这与我们经常习惯使用的指针计算一样,p 是一个结构体指针,那么 p+1 理当向后跳跃一个结构体类型的大小,即指向了结构体空间的后一个结构体空间的位置。并且我们知道 p 是一个全局变量,全局变量默认初始化为 0 ,那我们便可以知道,p=0 ,p+1=20 。 而 %p 是一个十六进制的打印格式,所以结果输出:00000014 。
在这里插入图片描述
(unsigned long)p + 0x1 似乎更简单一些。p 类型转换成了一个长整形,那么就代表 p 不再是一个指针,它存放的 0 就是单纯意义上的数字。所以 0 + 0x1 就等于 00000001 。

(unsigned int*)p + 0x1 也非常简单。p 本是一个结构体指针,现在强转为整形指针,这就代表着 p 进行加减整数的时候步幅由 20 个字节 变成了 4 个字节。那么 p=0 ,p+1=4 是毋庸置疑的。输出的结果为:00000004 。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值