指针进阶(4)看一下这些与指针有关的题你都会做吗?

news2024/11/17 8:05:41

9efbcbc3d25747719da38c01b3fa9b4f.gif

 c语言中的小小白-CSDN博客c语言中的小小白关注算法,c++,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm=1001.2014.3001.5343

给大家分享一句我很喜欢我话:

知不足而奋进,望远山而前行!!!

铁铁们,成功的路上必然是孤独且艰难的,但是我们不可以放弃,远山就在前方,但我们能力仍然不足,所有我们更要奋进前行!!!

今天我们更新了指针相关常见题型内容,

🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝

一、例子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;
}

我们先来看第一个例子,先创建一一维数组,然后第三行代码将创建一个指针ptr,指向变量a后面的内存位置。它通过使用 &a 获取变量a的地址,然后将其强制转换为 int* 类型指针。接下来,+1 操作将指针指向下一个 int 类型的内存位置。

然后看这张图片,第一个输出的是*(a+1),a是一个数组名,它在这里代表的是第一个元素的地址,然后+1,也就是输出第二个元素,所以第一个输出2,然后看*(ptr+1),ptr我们已经说了,代表的是&a+1,这里的&a代表的是整个数组的地址,然后+1之后其实是跳过整个数组,这里我们呢再来说一下表示整个数组的两种情况:

表示整个数组的地址

1. &arr 表示的是 整个数组 的 地址

2.sizeof(arr)中的arr表示的 是整个 数组

(此外的都表示首元素地址,或首行地址等等)

然后我们继续说这个题,此时跳过整个数组之后,&a+1代表的位置已经在图片中表示出来了,所以此时ptr-1在解引用代表的就是5这个元素了,所以会输出2,5

二、例子2

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

再看上述这串代码,这串代码的问题是,在x86的环境下,假设结构体的大小是20个字节,那么这串代码会输出什么,先来说一下x86环境是什么意思,其实就是在32位平台下

我们先来分析一下这串代码,我们创建了一个结构体,Test,然后在最后加了一个*,所以这是一个结构体指针,然后创建了一个结构体指针变量p,然后0x100000其实就是p里面存放的值,作为一个地址,然后我们前面说了结构体大小为20个字节,所以加1也就是跳过了20个字节,所以第一个应该是加20,但是0x100000是一个十六进制的数,因此将20转化为十六进制,结果就是0x100014。

然后我们看第二个,我们先把它强制类型转化成long,它就不再是指针了,然后整型值+1,其实就是+1,所以结果是0x100001,

最后我们来看第三个,第三个是强制类型转化为了int*类型,那么+1其实就是加4了,因为一个int*类型占据四个字节嘛,所以此时就是输出0x100004了

三、例子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,3,5};

然后接着往下走,创建一个指针p,然后令p=a[0],这里的a[0]就是第一行的数组名,数组名又表示首元素地址,然后输出p[0],也就是输出1.

下面我们运行代码看一下:

看来我们的推论是正确的。

四、例子4

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

在x86平台上,你认为这串代码会输出什么呢,

先来分析一下这串代码, int(*p)[4],创建一个数组指针,然后p指向的是四个整形元素的

然后把a赋给p,

然后我们看输出的元素是指针-指针类型的,指针-指针得到的是指针之间的元素个数的绝对值。

我们再来看一下p=a这一行,这是什么意思呢?我们知道,a是二维数组,然后二维数组的数组名代表着首元素地址,也就是第一行的地址,

看一下这张图,绿色包含的这一块就是a所代表的地方。然后我们看&p[4][2],这个其实就是             *(*(p+4)+2),但是p有自己的类型,p指向的数组是四个整形元素的,所以每次+1往后跳四个元素,

所以&p[4][2]就指向紫色填充的地方。然后这两个指针相减,之间有四个元素,然后低地址-高地址,所以结果是负数,换成二进制就是1000000000000000000000000000100(原码)111111111111111111111111111111011(反码)111111111111111111111111111111100(补码)

然后因为打印是按十六进制打印,补码换成十六进制就是FFFFFFFC

然后看第二个,以%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;
}

先看ptr1,%aa是取出的整个二维数组的地址所以加1就是跳过整个二维数组,所以打印*(ptr-1)结果就是10了

再看ptr2,

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

下面我们再来看一下这串代码,这串代码首先创建了一个数组a,然后每个元素都是一个char*类型

然后创建一个二级指针pa,存放char*类型的数组a的地址,a代表数组的首元素,然后pa++,所以pa就等于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;
}

最后我们来看一下这串代码,这串代码是这些代码中最复杂的一个,大家一定要跟着我的思路慢慢理解,

首先我们来画一个图,来表示这个代码的基本思路

这就是一个代码的大致思路。

然后我们看第一个**++cpp,这个代码限制性++这一步,++后cpp指向的便是c+2这里,然后两次解引用,我们便得到P的地址,然后输出P这个数组的字符串,便会输出POINT

然后我们看*--*++cpp+3,此时我们要知道cpp指向的是c+2这里,因为优先级我呢提,所以我们先执行cpp前面的内容,++cpp,那么此时cpp便指向c+1这里,然后解引用,再--,便指向E这里,然后解引用,然后再+3,所以此时就会输出ER这个字符串。

然后我们再来看一下第三个,*cpp[-2]+3,这里cpp[-2]的意思其实就是*(cpp-2),然后由上面可得cpp此时位于c那里,然后-2就会位于c+3的位置,然后再解引用,此时会指向F这里,然后+3,就会输出了ST

最后我们来看一下cpp[-1][-1]+1,转换成*(*(cpp-1)-1)+1,我们知道此时cpp还是位于c+1的位置,因为cpp[-2]不会改变cpp的位置然后cpp-1,得到c+2,然后再-1,再次得到c+1指向的位置,也就是N,然后再+1,也就输出EW了

总结:

这就是我们今天讲解的全部题目了,希望大家好好看一下,把这些题都搞懂,那么指针的学习也就合格了。

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

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

相关文章

JVM-垃圾收集器G1

G1垃圾回收器 概述&#xff1a; 是一款面向服务器的垃圾收集器,主要针对配备多个处理器及大容量内存的机器. 以极高效率满足GC停顿时间要求的同时,还具备高吞吐量性能特征.G1保留了年轻代和老年代的概念&#xff0c;但不再是物理隔阂了&#xff0c;它们都是&#xff08;可以不连…

供应链管理系统(SCM):得供应链得天下不是空话。

2023-08-26 15:51贝格前端工场 Hi&#xff0c;我是贝格前端工场&#xff0c;优化升级各类管理系统的界面和体验&#xff0c;是我们核心业务之一&#xff0c;欢迎老铁们评论点赞互动&#xff0c;有需求可以私信我们 一、供应链对于企业的重要性 供应链对企业经营的重要性不可…

在外包公司搞了2年,出来技术都没了...

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了2年的的功能…

O2O:Sample Efficient Offline-to-Online Reinforcement Learning

IEEE TKDE 2024 paper Introduction O2O存在策略探索受限以及分布偏移问题&#xff0c;进而导致在线微调阶段样本效率低。文章提出OEMA算法首先使用离线数据训练乐观的探索策略&#xff0c;然后提出基于元学习的优化方法&#xff0c;减少分布偏移并提高O2O的适应过程。 Meth…

Java零基础 - 数组的定义和声明

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一个人虽可以走的更快&#xff0c;但一群人可以走的更远。 我是一名后…

React-Redux中actions

一、同步actions 1.概念 说明&#xff1a;在reducers的同步修改方法中添加action对象参数&#xff0c;在调用actionCreater的时候传递参数&#xff0c;数会被传递到action对象payload属性上。 2.reducers对象 说明&#xff1a;声明函数同时接受参数 const counterStorecre…

DDoS和CC攻击的原理

目前最常见的网络攻击方式就是CC攻击和DDoS攻击这两种&#xff0c;很多互联网企业服务器遭到攻击后接入我们德迅云安全高防时会问到&#xff0c;什么是CC攻击&#xff0c;什么又是DDoS攻击&#xff0c;这两个有什么区别的&#xff0c;其实清楚它们的攻击原理&#xff0c;也就知…

mybatis中使用<choose><when><otherwise>标签实现根据条件查询不同sql

项目场景&#xff1a; 有时候业务层未进行条件处理那么在sql怎么操作呢,这里我是将c#版本的代码改成Java版本的时候出现的问题,因为c#没有业务层 更多操作是在sql中实现的 也就是业务层和编写sql地方一起写了,当我按照c#代码改Java到写sql时发现<if>标签不能实现我们业务…

3.8 动态规划 背包问题

一.01背包 46. 携带研究材料&#xff08;第六期模拟笔试&#xff09; (kamacoder.com) 代码随想录 (programmercarl.com) 携带研究材料: 时间限制&#xff1a;5.000S 空间限制&#xff1a;128MB 题目描述: 小明是一位科学家&#xff0c;他需要参加一场重要的国际科学大会…

OpenCascade源码剖析:Handle类

Handle其实就是智能指针的上古版本&#xff0c;了解一点C11的应该对shared_ptr非常熟悉&#xff0c;那么你就把Handle当做shared_ptr来理解就没有任何问题了。 不过OCCT的Handles是侵入式的实现&#xff0c;前面讲过Standard_Transient类提供了引用计数机制&#xff0c;这个就…

新质生产力助春播春管:佳格天地连续第5年上线大数据平台,服务春季生产

随着“惊蛰”节气过去,全国各地陆续掀起春播春管热潮。今年的政府工作报告中指出,2023年我国粮食产量1.39万亿斤,再创新高。2024年要坚持不懈抓好“三农”工作,扎实推进乡村全面振兴,粮食产量预期目标1.3万亿斤以上。 粮食产量预期目标的明确为一年农事生产指引了方向。同时,新…

地址分词 | EXCEL批量进行地址分词,标准化为十一级地址

一 需求 物流需要对用户输入地址进行检查&#xff0c;受用户录入习惯地址可能存在多种问题。 地址标准化是基于地址引擎和地址大数据模型&#xff0c;自动将地址信息标准化为省、市、区市县、街镇、小区、楼栋、单元、楼层、房屋、房间等元素&#xff0c;补充层级缺失数据、构建…

导出谷歌gemma模型为ONNX

参考代码如下&#xff08;从GitHub - luchangli03/export_llama_to_onnx: export llama to onnx修改而来&#xff0c;后面会合入进去&#xff09; 模型权重链接参考&#xff1a; https://huggingface.co/google/gemma-2b-it 可以对modeling_gemma.py进行一些修改(transforme…

LLCC68与SX1278 LoRa模块的优势对比?

LLCC68和SX1278都是Semtech公司推出的LoRa调制解调器模块&#xff0c;属于LoRa模块家族。它们在无线通信领域都有着广泛的应用&#xff0c;但具体的优势会取决于具体的应用场景和需求。下面是对LLCC68和SX1278 LoRa模块的一些优势对比&#xff1a; LLCC68 LoRa模块的优势&#…

qt自定义时间选择控件窗口

效果如图&#xff1a; 布局如图&#xff1a; 参考代码&#xff1a; //DateTimeSelectWidget #ifndef DATETIMESELECTWIDGET_H #define DATETIMESELECTWIDGET_H#include <QWidget> #include <QDateTime>namespace Ui { class DateTimeSelectWidget; }class DateTim…

【手游联运平台搭建】游戏平台的作用

随着科技的不断发展&#xff0c;游戏行业也在不断壮大&#xff0c;而游戏平台作为连接玩家与游戏的桥梁&#xff0c;发挥着越来越重要的作用。游戏平台不仅为玩家提供了便捷的游戏体验&#xff0c;还为游戏开发者提供了广阔的市场和推广渠道。本文将从多个方面探讨游戏平台的作…

扩展CArray类,增加Contain函数

CArray不包含查找类的函数&#xff0c;使用不便。考虑扩展CArray类&#xff0c;增加Contain函数&#xff0c;通过回调函数暴露数组元素的比较方法&#xff0c;由外部定义。该方法相对重载数组元素的“”符号更加灵活&#xff0c;可以根据需要配置不同的回调函数进行比较 //类型…

继深圳后,重庆与鸿蒙展开原生应用开发合作

截至2023年底&#xff0c;开源鸿蒙开源社区已有250多家生态伙伴加入&#xff0c;开源鸿蒙项目捐赠人达35家&#xff0c;通过开源鸿蒙兼容性测评的伙伴达173个&#xff0c;累计落地230余款商用设备&#xff0c;涵盖金融、教育、智能家居、交通、数字政府、工业、医疗等各领域。 …

底层day3作业

思维导图 作业&#xff1a;1.总结任务的调度算法&#xff0c;把实现代码再写一下 算法&#xff1a;抢占式调度时间片轮转 1.抢占式调度&#xff1a;任务优先级高的可以打断任务优先级低的执行&#xff08;适用于不同优先级&#xff09; 2.时间片轮转&#xff1a;每一个任务拥…

react的diff源码

react 的 render 阶段&#xff0c;其中 begin 时会调用 reconcileChildren 函数&#xff0c; reconcileChildren 中做的事情就是 react 知名的 diff 过程 diff 算法介绍 react 的每次更新&#xff0c;都会将新的 ReactElement 内容与旧的 fiber 树作对比&#xff0c;比较出它们…