12. 《C语言》——【指针运算笔试题解析】


在这里插入图片描述


前言

	今天分享几道这个关于指针运算的笔试题,希望能够帮助到各位老板。那么接下来,就让我们一起看看~

练习题


练习题1

代码如下:

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

运行结果:

在这里插入图片描述

分析:

  1. 首先,我们通过画图来解析:
    在这里插入图片描述
  2. 我们看到,这是一个数组,元素类型都是int。然后,int* ptr = (int*)(&a + 1); &a是数组的地址和数组首元素的地址是一样的,是在上图的红色&a,对它进行+1,就到了图中红色的 &a+1 , 这涉及到了指针的+ - ,对它进行强转为(int*)赋值给指针变量ptr。
  3. ptr指向的位置和&a+1是一样的,最后ptr - 1再进行解引用,就得到了5。
  4. *(a+1),a是数组名,是数组首元素,指向的对应图中紫色a,那么a+1,就对应图中紫色的a+1,对它进行解引用,得到的就是2。
  5. 最终的打印结果就是:2,5

练习题2

代码如下:

//指针运算练习题2
//在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;
}

运行结果:

在这里插入图片描述

分析:

  1. 注意,题目要求是在X86环境下运行的。
  2. p+0x1,0x1是16进制也就是1,p是结构体指针,+1就是跳过一个结构体,结构体的大小是20个字节,最后打印:00100014
  3. (unsigned long)p + 0x1,p的类型是无符号长整形,对它进行+1,最后打印:00100001
  4. (unsigned int*)p + 0x1,p的类型是无符号整型指针,+1,就跳过了一个整型的大小,最后打印:00100004

练习题3

代码如下:

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

运行结果:

在这里插入图片描述

分析:

  1. 通过调式我们得到下图:
    在这里插入图片描述
  2. 我们可以看到,这是一个二维数组,对二维数组初始化我们应该用花括号,但是,代码中使用的是圆括号。这其实是一个逗号表达式,逗号表达式取的是最后的值,所以就得到上图。
  3. a[0]表示数组首元素,那么数组首元素就是1。然后赋值给指针变量p,最后打印得到1

练习题4

代码如下:

//假设环境是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;
}

运行结果:

在这里插入图片描述

分析:

  1. 要求是在x86环境下,我们用画图来解析;
    在这里插入图片描述
  2. &p[4][2] - &a[4][2] , 得到的是-4,但是打印是%p,以地址的形式打印出来是不在乎原反补码的,所以打印的是-4的补码以%p的形式打印出来,所以得到:FFFFFFFC。
  3. 以%d的形式打印,就得到-4。

练习题5

代码如下:

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

运行结果:

在这里插入图片描述

分析:

  1. 我们画图分析:
    在这里插入图片描述
  2. 这是一个二维数组,我们已经在图上画出,&aa是数组的地址,+1跳过了一个数组。然后赋值给了整型指针变量ptr1,ptr1-1就得到了10。
  3. aa是数组首元素,+1,指向了aa[1] , 赋值给了ptr2,ptr2-1,就得到了5

练习题6

代码如下:

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

运行结果:

在这里插入图片描述

分析:

  1. 这是一个指针数组,把a给了char ** pa这是个二级指针,pa++自增,指向了at,打印是字符串格式,最后输出at。

练习题7

代码如下:

#include <stdio.h>
int main()
{
	char* c[] = { "ENTER","NEW","POINT","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;
}

运行结果:

在这里插入图片描述

分析:

  1. 看下图,一开始cpp是指向蓝色线c+3的,然后++cpp,指向了红色线c+2,解引用得到了point。
    在这里插入图片描述
  2. 看下图,因为之前的自增,cpp已经指向了红色线c+2,++cpp紫色线指向了c+1,解引用得到了c+1,然后自减得到了c,再进行解引用,得到了enter,那么指向了e,然后+3,最后得到er。
    在这里插入图片描述
  3. 看下图,之前是指向紫色线c+1,*cpp[-2] = *(cpp-2) ,指向了橙色线,进行解引用得到了first,然后+3,最后打印st。

在这里插入图片描述

  1. 看下图,之前是指向橙色线c+3,然后cpp[-1][-1]+1 = * (* (cpp-1) -1) + 1 , 指向了粉色线c+1,解引用得到了new,进行+1,最后打印ew。
    在这里插入图片描述

总结

  1. 以上就是今天要讲的内容,总共讲了7个练习题,希望对各位老板能有所帮助!
  2. 也希望各位老板,能够点个赞和一个关注,这是对我莫大的鼓励 ~

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值