C语言数组和指针笔试题(五)(一定要看)

news2025/1/14 1:19:16

这里写目录标题

  • 指针运算笔试题解析
    • 题目1
      • 解析
      • 结果
    • 题目2
      • 解析
      • 结果
    • 题目3
      • 解析
      • 结果
    • 题目4
      • 解析
      • 结果
    • 题目5
      • 解析
      • 结果
    • 题目6
      • 解析
      • 结果
    • 题目7
      • 解析
      • 结果
    • 题目8
      • 解析
      • 结果

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒个人主页
🥸🥸🥸C语言
🐿️🐿️🐿️C语言例题
🐣🐓🏀python

指针运算笔试题解析

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

解析

a[5]是一个整形类型的数组,&a是取的整个数组的地址,因此&a+1就是跳过整个数组,(int*)是强制类型转换,是将&a+1强制转换成int类型的指针(&a+1也可以写成int(*)[5])

*(a+1)中的a是数组首元素的地址,a+1=&a[1],解引用结果就是a[1]=2

ptr-1这里就要好好说一下了,我们用一个图来表示
在这里插入图片描述
如图因为&a+1是跳过整个数组,因此ptr的地址在a[4]之后,与a[4]相差4个字节,而ptr-1是跳过1个元素,也就是往前跳过4个字节,因此ptr-1的地址其实就是&a[4],解引用之后就是a[4]=5

结果

在这里插入图片描述

题目2

//在X86环境下,假设结构体的大小是20个字节,程序输出的结构是什么
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;
}

解析

0x开头的是16进制,因此0x1其实就是1,p是结构体指针,因为结构体指针+1是跳过一个结构体的大小,而结构体大小是20个字节,又因为是16进制,所以结果是0x100014

,(unsigned long)p是将p强制类型转换为无符号的long,所以p+1就是0x100001

而printf(“%p\n”, (unsigned int*)p + 0x1),因为是将p转换为无符号整形指针,所以+1就是跳过4个字节,就是0x100004

因为是16进制的地址,所以需要4个字节,结果是
0x00100014
0x00100001
0x00100004

结果

在这里插入图片描述

题目3

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

解析

int* ptr1 = (int*)(&a + 1)和第一题是一样的所以就不解释了

int* ptr2 = (int*)((int)a + 1)中(int)a是将a强制转换为整形类型,因为整形类型的运算和数学运算是差不多的,因此这里的+1其实就数学上的+1,举个例子假如a的地址是0x0012ff40,通过转换这个地址对应的数字是1244992,所以(int)a+1其实就是1244992+1=1244993,然后将这个结果强制类型转换为整形指针,所以转换之后的地址就是0x0012ff41

我们知道内存存储是分大小端的,这里VS是用小端存储
在这里插入图片描述
当用%x打印是02 00 00 00中2前面的0不会打印,所以结果是2000000

而*ptr打印就是4

结果

在这里插入图片描述

题目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)就是1,因此二维数组我们可以这样写,a[3][2]={1,3,5};因为是三行二列,而{ }中只有三个元素,剩下的既全为0,a[0]在上一篇博客已经讲了,是一维数组{1,3}的数组名,因为p=a[0],所以p[0]=a[0][0],最后结果就应该是1

结果

在这里插入图片描述

题目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]是一个数组指针,因为p=a中a是数组名表示数组首元素的地址,所以a其实就是int( * )[5],而p是int()[4]

在这里插入图片描述
因为p中只有4个元素,所以p+1就是跳过4个整形元素,因此绿色是p+4所包含的元素,红色就是a[4][2],对于&p[4][2] - &a[4][2]就是-4,用%p来打印的话就需要将-4的补码写出来

-4的原码:10000000 00000000 00000000 00000100
反码: 111111111 111111111 111111111 111111011
补码: 111111111 111111111 111111111 111111100
因为是打印的%p是地址,所以将补码看成16进制来打印,结果是FFFFFFFC
而用%d打印的话其实就是-4

结果

在这里插入图片描述

题目6

#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中&aa是整个二维数组的地址,因此&aa+1是跳过整个二维数组,(int*)将&aa+1强制转换为整形类型的指针

(aa+1)中aa是第一行的地址,(aa+1)就是aa[1],aa[1]就行相当于第二行的数组名,aa[1]=&aa[1][0],这里的强制类型转换其实是多余的,因为第二行第一个元素本来就是整形,取他的地址就是整形类型的指针

所以*(ptr1-1)就是10,*(ptr2-1)就是5

结果

在这里插入图片描述

题目7

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

解析

这是一道阿里巴巴的笔试题
chara[]是一个数组,数组里面的类型都是char,数组括号里面都是三个字符串,但是这三个字符串是放不下,因为这个数组里面的都指针char*,字符串是放不进去的,所以放进去的是他们的地址,比如work存放在a中的地址是w的地址,at存放的则是a地址…

而pa存放的是a的首元素地址,pa++后就是a的第二个元素如图
在这里插入图片描述

结果

在这里插入图片描述

题目8

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

解析

在这里插入图片描述
上面是没有进行自增自减操作时每个数组元素对应的地址
char*c中存储的分别是
ENTER中E的地址
NEW中N的地址
POINT中P的地址
FIRST中F的地址
而cp中c+3就是第四个元素的地址,c+2就是第三个元素的地址…
cpp是将cp的首元素地址传给cpp,所以cpp就是c+3的地址
在这里插入图片描述
上图是经过自增自减操做后的结果,
printf(“%s\n”, **++cpp);对应的颜色是红
printf(“%s\n”, *-- * ++cpp + 3);对应的颜色是绿
printf(“%s\n”, *cpp[-2] + 3);对应的颜色是黑
printf(“%s\n”, cpp[-1][-1] + 1);对应的颜色是粉
我们一个一个的解析
第一次打印: **++cpp先将cpp进行自增,所以cpp中的cp从cp中第一个元素c+3变到第二个元素c+2 然后两次解引用之后就是POINT中P的地址,打印字符串就为POINT
第二次打印:由于++cpp将cpp中cp指向的地址永久变化了,所以第二次的++cpp就是从c+2变到了c+1,解引用再–,c+1就变成了c,所以c+1指向的地址就由1变成0,之后再解引用就是ENTER中E的地址,再+3后,就是箭头值的第二个E的地址,打印字符串就是ER
第三次打印:*cpp[-2]+3我们可以写成 * *(cpp-2)+3,由于上一次打印使cpp指向的c+2变成了c+1,所以这里的cpp-2就使cpp指向的第三个元素c+1变为第一个元素c+3(注意这里不是自增自减),再经过两次解引用后,就是FIRST中F的地址,+3就变成了箭头指向的S的地址,所以打印结果为ST
第四次打印cpp[-1][-1] + 1可以写成 *( *(cpp-1)-1)+1,cpp-1就是从第三个元素c+1变为第二个元素c+2,解引用再-1就是从原来指向的下标2变成指向的下标1,解引用再+1就是NEW中E的地址,打印的结果就是EW

结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1057977.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【智能家居项目】裸机版本——设备子系统(LED Display 风扇)

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 输入子系统中目前仅实现了按键输入&#xff0c;剩下的网络输入和标准输入在以后会逐步实现&am…

生鲜蔬果同城配送社区团购小程序商城的作用是什么

生鲜蔬果行业作为市场主要支撑之一&#xff0c;从业商家众多的同时消费者也从不缺&#xff0c;尤其对中高城市&#xff0c;生鲜蔬果除了传统线下超市、市场经营外&#xff0c;线上更是受到大量消费者信任&#xff0c;而很多商家也是自建了生鲜蔬果商城多场景生意经营。 那么通…

家具商家通过商城小程序发展的作用是什么

家具商品覆盖床具、桌椅茶几、沙发等多个细分种类&#xff0c;市场需求较高&#xff0c;而传统消费者也是通过线下方式购买配送&#xff0c;但随着线下经营痛点显现&#xff0c;如流量匮乏拓客难、无法满足同城外地客户随时购物需求、营销难、经营难等&#xff0c;因此不少商家…

第九章 动态规划 part14 1143. 最长公共子序列 1035. 不相交的线 53. 最大子序和

第五十六天| 第九章 动态规划 part14 1143. 最长公共子序列 1035. 不相交的线 53. 最大子序和 一、1143. 最长公共子序列 题目链接&#xff1a; 题目介绍&#xff1a; 思路&#xff1a; 本题和“最长重复子数组”区别在于**这里不要求是连续的了&#xff0c;但要有相对顺序*…

安防监控用品经营商城小程序搭建

安防监控产品种类很多&#xff0c;如监控摄像头、烟感、机房系统、对讲机等&#xff0c;虽然不是每个家庭都需要&#xff0c;但却占据着市场不小份额&#xff0c;其应用度也非常广泛&#xff0c; 而在实际销售方面&#xff0c;除了门店、入驻第三方电商平台或朋友圈售卖外&…

Docker 容器监控 - Weave Scope

Author&#xff1a;rab 目录 前言一、环境二、部署三、监控3.1 容器监控 - 单 Host3.2 容器监控 - 多 Host 总结 前言 Docker 容器的监控方式有很多&#xff0c;如 cAdvisor、Prometheus 等。今天我们来看看其另一种监控方式 —— Weave Scope&#xff0c;此监控方法似乎用的人…

ctfshow—1024系列练习

1024 柏拉图 有点像rce远程执行&#xff0c;有四个按钮&#xff0c;分别对应四份php文件&#xff0c;开始搞一下。一开始&#xff0c;先要试探出 文件上传到哪里&#xff1f; 怎么读取上传的文件&#xff1f; 第一步&#xff1a;试探上传文件位置 直接用burp抓包&#xff0c;…

PowerPoint如何设置密码?

PowerPoint&#xff0c;也就是PPT&#xff0c;是很多人工作中经常用的办公软件&#xff0c;而PPT和Word、Excel等一样可以设置密码保护。 PPT可以设置两种密码&#xff0c;一种是“打开密码”&#xff0c;也就是需要密码才能打开PPT&#xff1b;还有一种是设置成有密码的“只读…

python实现http/https拦截

python实现http拦截 前言:为什么要使用http拦截一、技术调研二、技术选择三、使用方法前言:为什么要使用http拦截 大多数爬虫玩家会直接选择API请求数据,但是有的网站需要解决扫码登录、Cookie校验、数字签名等,这种方法实现时间长,难度高。需求里面不需要高并发,有没有…

Docker系列--在容器中安装JDK的方法(有示例)

原文网址&#xff1a;Docker系列--在容器中安装JDK的方法(有示例)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍如何在容器中安装JDK。 为什么要装JDK&#xff1f; JDK里有很多工具&#xff0c;比如jps、jstack、jmap等&#xff0c;可以排查问题。 本文目标 给Ubuntu系…

【数据结构】海量数据处理

【数据结构】海量数据处理 前言 海量数据处理是指基于海量数据的存储和处理&#xff0c;正因为数据量太大&#xff0c;所以导致要么无法在短时间内迅速处理&#xff0c;要么无法一次性装入内存。 对于时间问题&#xff0c;就可以采用位图、布隆过滤器等数据结构来解决。对于…

摄影后期图像编辑软件Lightroom Classic 2023 mac中文特点介绍

Lightroom Classic 2023 mac是一款图像处理软件&#xff0c;是数字摄影后期制作的重要工具之一&#xff0c;lrc2023 mac适合数字摄影后期制作、摄影师、设计师等专业人士使用。 Lightroom Classic 2023 mac软件特点 高效的图像管理&#xff1a;Lightroom Classic提供了强大的图…

分布式应用程序协调服务 ZooKeeper 详解

目录 1、ZooKeeper简介 2、ZooKeeper的使用场景 3、ZooKeeper设计目的 4、ZooKeeper数据模型 5、ZooKeeper几个重要概念 5.1、ZooKeeper Session 5.2、ZooKeeper Watch 5.3、Consistency Guarantees 6、ZooKeeper的工作原理 6.1、Leader Election 6.2、Leader工作流…

Docker中MySql容器的数据挂载

1.查看是否有数据卷 docker inspect mysql 说明&#xff1a;Name的值是随机生成的不是命令的。因此没有数据卷。 2. 目录挂载 说明&#xff1a;本地目录不允许简写&#xff1b;在执行docker runi命令时&#xff0c;使用-v本地目录&#xff1a;容器内目录可以完成本地目录挂载…

Python之函数、模块、包库

函数、模块、包库基础概念和作用 A、函数 减少代码重复 将复杂问题代码分解成简单模块 提高代码可读性 复用老代码 """ 函数 """# 定义一个函数 def my_fuvtion():# 函数执行部分print(这是一个函数)# 定义带有参数的函数 def say_hello(n…

列表的增删改查和遍历

任务概念 什么是任务 任务是一个参数为指针&#xff0c;无法返回的函数&#xff0c;函数体为死循环不能返回任务的实现过程 每个任务是独立的&#xff0c;需要为任务分别分配栈称为任务栈&#xff0c;通常是预定义的全局数组&#xff0c;也可以是动态分配的一段内存空间&#…

农产品团购配送商城小程序的作用是什么

农产品覆盖稻麦油蛋等多种细分类目&#xff0c;各地区经营商家众多&#xff0c;随着人们生活品质提升&#xff0c;对食物的要求也在提升&#xff0c;绿色无污染无激素的农产品往往受到不少人喜爱&#xff0c;而在销售中&#xff0c;也有不少人选择自建商城线上经营。 通过【雨…

【软考】磁盘工作原理 计算最多最少读取时间

这个题目重复看了三四遍讲解&#xff0c;才完全搞懂计算过程&#xff0c;特此记录 解析 磁头不会停止旋转 单缓冲区&#xff1a;读取完一个物理块后&#xff0c;只有等该物理块处理完成&#xff0c;才能继续读取后面的物理块。 最长时间 摆放顺序如下&#xff1a; 从 R0 开始…

【JavaEE】JavaScript webAPI的基本知识

JavaScript Web API 文章目录 JavaScript Web APIwebAPI背景DOMDOM树 获取元素querySelectorquerySelectorAll 事件初识键盘事件onkeydownonkeypressonkeyup 操作元素获取/修改元素内容1.innerText2.innerHTML 获取/修改元素属性获取/修改表单元素属性获取/修改样式属性行内样式…

JUC——并发编程—第四部分

理解JMM Volatile是Java虚拟机提供的轻量级的同步机制。有三大特性。 1.保证可见性 2.不保证原子性 3.禁止指令重排 定义:Java内存模型&#xff0c;是一个概念。 关于JMM的一些同步的约定: 1、线程解锁前&#xff0c;必须把共享变量立刻刷回主存. 2、线程加锁前&#x…