八道指针笔试题

news2024/12/23 23:57:08

请添加图片描述


文章目录

  • 笔试题1
  • 笔试题2
  • 笔试题3
  • 笔试题4
  • 笔试题5
  • 笔试题6
  • 笔试题7
  • 笔试题8


笔试题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,其有5个元素每个元素为int型。接着&a(取出的是整个数组a的地址,因为&数组名取出的是整个数组的地址),然后+1(跳过一整个数组,也就是数组a,地址指向数组末尾的位置;原因是:地址(指针)的类型的决定了加减整数时的步长),最后将这个地址强制类型转化为int*,再赋值给int* ptr。内存布局如下图所示:

在这里插入图片描述

  所以*(a + 1)就是在访问数组a第二个元素,也就是这里的2;*(ptr - 1)就是在访问数组a第五个元素,也就是这里的5(因为地址(指针)的类型决定了其在解引用操作的时候能过访问空间的大小,即:int型指针解引用访问int型大小的空间,char型指针解引用访问char型大小的空间)。故printf打印的及如果为2,5

在这里插入图片描述


笔试题2

//已知,结构体Test的类型大小是20个字节,假设p 的值为0x100000。
//问:如下表表达式的值分别为多少?
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;
}

  首先创建了一个结构体类型Test,然后用该结构体类型定义了的指针变量p,并初始化为0x100000(也就是使指针p指向了地址为0x100000的内存空间)。接着调用主函数:

  第一个printf:打印的是p + 0x1的地址,也就是p+1的地址(因为这里的0x1表示的是十六进制的1,转化为十进制也是1)。由于p是一个指向Test类型结构体的指针,所以+1就是跳过一个该类型结构体的大小,也就是20个字节,故打印结果为0x100000 + 20 = 0x100014

  第二个printf:打印的是(unsigned long)p + 0x1,运算顺序是先将指针强制类型转化为unsigned long类型,也就是无符号长整形,那对整型+1不就仅仅只是加一嘛。故表达式(unsigned long)p + 0x1的结果为0x100001,然后printf以地址类型打印整型类型的0x100001,结果为:0x100001

  第三个printf:打印的是(unsigned int*)p + 0x1,与之前一样先强制类型转化unsigned int*注意:这可是一个指针类型啊,加减整数可不仅仅只是加减整数),所以这里的p+1其实是跳过了一个int型的大小,也就是4个字节。故打印结果为:0x100000 + 4 = 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;
}
//问:打印结果是什么?

  首先创建了一个int [4]型的数组,然后为int*类型的指针ptr1和ptr2赋值,其中int *ptr1 = (int *)(&a + 1);与笔试1类似,指向的是数组a的末尾。这道题主要考点这于(int *)((int)a + 1),它先是将a强制类型转化为int型,也就是将数组a首元素的地址强制类型转化为int型,当成整型来看(因为数组名一般情况下表示数组首元素的地址)。然后对其+1,自然结果仅仅就是加一,然后将得到的这个整型数强制类型转化为(int*)后赋值给pt2,故此时ptr2指向的就是数组首元素地址向后跳一个字节后的空间。内存布局如下图所示:

在这里插入图片描述

  最后打印ptr1[-1]等价于*(ptr-1),printf是以%x(十六进制)的形式打印,所以最后的结果为:4,2000000

在这里插入图片描述


笔试题4

int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf( "%d", p[0]);
return 0;
}
//问:最后打印结果是什么?

  首先定义了一个3行2列的二维数组,然后对其初始化{ (0, 1), (2, 3), (4, 5) },大家有没有觉得很变扭,初始化二维数组什么时候用()啦?不因该是{ {0, 1}, {2, 3}, {4, 5} }这样嘛。所以这里的()并不是代表一行,而因该是逗号表达式,故这里的初始化因该是不完全初始化,内存布局如下图所示:
在这里插入图片描述
  接着将p = a[0];,其中a[0]表示的数组a第一行的数组名,而数组名又表示数组首元素的地址,故这里的a[0]表示第一行首元素的地址,即a[0][0]的地址。然后printf打印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;
}
//问:最后打印结果是什么?

  首先创建了一个5行5列的二维数组a,然后又创建了一个数组指针p(其指向的数组有4个元素,每个元素都是int型的)。我们有知道二维数组的数组名本质上表示的是第一行的地址,p = a;就是将二维数组a第一行的地址赋值给了数组指针p(注意:虽然它两的类型不同,但传递的值是不变的),故你会发现此时a和p指向了同一个位置。

  其实我们完全可以把p和a都看成二维数组(只不过这两个二维数组的起始位置是相同的,而且p代表的二维数组每行只有4个元素,而a代表的每行却有5个元素)。然后来理解 &p[4][2] - &a[4][2],这求的不就是两个地址之间元素的个数嘛(因为指针 ‘-’ 指针的值是,指针之间元素的个数),而且是二维数组p第4行第2列元素地址与二维数组a第4行第2列元素地址之间元素的个数,那不就只要知道p[4][2]前元素的个数和a[4][2]前元素的个数之后相减就可以得到想要的结果了(注意:指针‘-’指针的值也可能会是负数)。p[4][2]前元素的个数是4 * 4 + 2 = 18a[4][2]前元素的个数是4 * 5 + 2 = 22,故&p[4][2] - &a[4][2]的结果为 -4 。内存布局如下图所示:

在这里插入图片描述

  然而这道题还没有做完,他还考了一个知识点,printf是要以两种不同的形式分别输出&p[4][2] - &a[4][2]表达式的结果。我们知道%d表示是以有符号整型输出,故输出因该是:-4。而%p是专门用来打印地址的(而且是十六进制形式输出),但我们要知道地址在存放的时候可没有原码、反码、补码这么一说,它是直接放入内存当中的,故取的时候也直接取就完事了,不需要经过任何的转换(即内存当中是什么,打印的就是什么)。打印结果就是-4的补码,即:ff ff ff fc。

在这里插入图片描述


笔试题6

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;
}
//问:最后打印结果是什么?

  首先创建了一个2行5列的二维数组aa,然后你会发现这题的考点其实与之例题3的考点差不多。只不过是将一维数组的数组名换成了二维数组的数组名罢了。下面看内存布局:

在这里插入图片描述
在这里插入图片描述


笔试题7

int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}
//问:最后打印结果是什么?

  首先创建了一个字符指针数组,然后使每一个字符指针都指向一个常量字符串,接着创建了一个二级指针pa,让其指向指针数组a首元素a[0]。内存布局如下图所示:

在这里插入图片描述
  *pa访问的是a[1],而a[1]中存放的是字符串“at”首字符a的地址,所以printf打印的结果是“at”。

在这里插入图片描述


笔试题8

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;
}
//问:最后打印结果是什么?

  关于这道题大家就不要吝啬你的草稿纸了,内存布局画出来分析吧,不然光靠想是做不出来的,因为太过于混乱了。内存布局如下图所示:

在这里插入图片描述
  接下来就是简单的根据表达式的优先级的运算,来最终求出打印的结果。

在这里插入图片描述


在这里插入图片描述

这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀。

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

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

相关文章

数据结构————双链表

目录 一、单链表的定义及其特点 定义: 特点: 双链表的优缺点 双链表的关键特性 二、双链表的实现 准备工作: 自定义数据元素类型: 1.双链表的创建 1.1头插法介绍 1.2尾插法介绍 2.双链表的初始化 3.双链表的求表长 4.…

TDengine 与 SCADA 强强联合:提升工业数据管理的效率与精准

随着时序数据库(Time Series Database)的日益普及,越来越多的工业自动化控制(工控)人员开始认识到其强大能力。然而,时序数据库在传统实时数据库应用领域,特别是在过程监控层的推广仍面临挑战&a…

cmd命令

常用命令 查看电脑名称: hostname 查看网卡信息: ipconfig 快速打开网络设置界面: control.exe netconnections 或 rundll32.exe shell32.dll,Control_RunDLL ncpa.cpld 打开防火墙设置: wf.msc 指定网卡设置IP地址&#…

linux_L1_linux重启服务器

使用putty登录到linux服务器切换到管理员账号 sudo -s重启命令 reboot

Unity全面取消Runtime费用 安装游戏不再收版费

Unity宣布他们已经废除了争议性的Runtime费用,该费用于2023年9月引入,定于1月1日开始收取。Runtime费用起初是打算根据使用Unity引擎安装游戏的次数收取版权费。2023年9月晚些时候,该公司部分收回了计划,称Runtime费用只适用于订阅…

ROS1录包偶现一次崩溃问题定位

现象&#xff1a;崩到了mogo_reporter里面 堆栈&#xff1a;crash里面同时存在两个主线程的堆栈 代码 #include "boost/program_options.hpp" #include <signal.h> #include <string> #include <sstream> #include <iostream> #include <…

【PSINS】ZUPT代码解析(PSINS_SINS_ZUPT)|MATLAB

这篇文章写关于PSINS_SINS_ZUPT的相关解析。【值得注意的是】:例程里面给的这个m文件的代码,并没有使用ZUPT的相关技术,只是一个速度观测的EKF 简述程序作用 主要作用是进行基于零速更新(ZUPT)的惯性导航系统(INS)仿真和滤波 什么是ZUPT ZUPT是Zero Velocity Update(…

828华为云征文 | 使用华为云Flexus云服务器X安装搭建crmeb多门店商城教程

&#x1f680;【商城小程序&#xff0c;加速启航&#xff01;华为云Flexus X服务器助力您的业务腾飞】&#x1f680; 1、点击链接进入华为云官网&#xff0c;页面如下&#xff1a; 华为云Flexus云服务器X选购页面 https://www.huaweicloud.com/product/flexus-x.html 2、进…

Uniapp + Vue3 + Vite +Uview + Pinia 实现提交订单以及支付功能(最新附源码保姆级)

Uniapp Vue3 Vite Uview Pinia 实现提交订单以及支付功能&#xff08;最新附源码保姆级&#xff09; 1 效果展示2 提交订单2.1 cart.js2.2 submit-order.vue 3、支付页面order-pay.vue 1 效果展示 2 提交订单 2.1 cart.js // src/pages/store/cart/cart.js import {defineS…

【最新华为OD机试E卷】报文响应时间(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

mybatis获取参数的5种情况

Mybatis获取参数值的两种方式 mybatis获取参数值的方式有两种: ${} 和 #{} ${} 这个的本质就是字符串拼接 这个无法避免sql注入攻击 #{} 这个的本质就是占位符(尽量使用 #{} 的方式) 可以避免sql注入 mybatis获取参数值的情况 1.mapper接口方法的参数为单个字面量类型…

solidity-20-sendeth

发送ETH 这章的标题让我觉得奇怪&#xff0c;因为先前我也发送ETH&#xff0c;如上一篇提到的recieve和fallback函数。 重现了教程中的代码 // SPDX-License-Identifier: MIT pragma solidity ^0.8.21;contract sendeth{// 这个事件是为了打log,记录收到的eth和剩余的gas fee…

echarts中tooptips提示框超出了怎么解决

我们在制作echarts表格时&#xff0c;有时候会遇到提示框内容较多&#xff0c;会让提示框超出&#xff0c;展示不全数据&#xff0c;如下&#xff1a; 这种情况下需要在tooltips下增加一些属性&#xff1a; 1.confine: true&#xff1a;这个配置的作用是让提示框&#xff08;t…

Docker笔记-容器数据卷

Docker笔记-容器数据卷 docker的理念将运行的环境打包形成容器运行&#xff0c;运行可以伴随容器&#xff0c;但是我们对数据的要求是希望持久化&#xff0c;容器 之间可以共享数据&#xff0c;Docker容器产生的数据&#xff0c;如果不通过docker commit生成新的镜像&#xf…

大数据新视界 --大数据大厂之数据挖掘入门:用 R 语言开启数据宝藏的探索之旅

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

类型转换等 面试真题

题目1 请问哪个结果为NaN A. 123null B. 123‘1’ C. 123/0 D. 123undefined 在这四个表达式中&#xff0c;只有D. 123 undefined 的结果是 NaN&#xff0c;原因如下&#xff1a; A. 123 null 结果是&#xff1a;123原因&#xff1a;null 在数值运算中会被自动转换为 0&a…

mac上什么压缩软件没有广告,苹果电脑解压软件BetterZip有广告吗

mac上有很多压缩软件&#xff0c;可以帮助用户压缩或解压各种格式的文件&#xff0c;如zip、rar、7z等。但是&#xff0c;有些压缩软件会在使用过程中弹出广告&#xff0c;影响用户的体验和效率。那么&#xff0c;mac上什么压缩软件没有广告呢&#xff1f;苹果电脑解压软件Bett…

一步步教你利用大模型开发个性化AI应用,告别‘人工智障’!

为了回答这个问题&#xff0c;我用说人话的方式拿gpts创建了一个“我”&#xff0c;然后让她来回答这个问题。&#xff08;确认过眼神&#xff0c;我是懂套娃的&#xff09; 接下来我会先展示下整个定制过程&#xff1b;然后我们一起看一下她能把题答到什么程度&#xff1b;最后…

UnrealEngine 打包Android平台应用

虚幻引擎 支持将项目发布到 安卓&#xff08;Android&#xff09; 移动设备上&#xff0c;并且提供了若干功能帮你将项目发布到 谷歌游戏商店。本节包含了如何设置Android开发环境、如何使用Android功能和服务、以及如何为发布游戏做准备相关的指南。 当前SDK要求 当前UE版本…

JavaSE篇之内部类和图书系统

1.内部类(类中类) 在Java中&#xff0c;将一个类定义在另一个类内部&#xff0c;前者称为内部类&#xff0c;后者称为外部类。 注意事项&#xff1a; 1. 1.静态内部类&#xff08;被static修饰的内部类&#xff09; 1.在静态内部类的方法中不能直接引用外部类的成员变量&…