深入理解:指针变量的解引用 与 加法运算
前言
指针变量的解引用和加法运算是非常高频的考点,也是难点,因为对初学者的不友好,这就导致了各大考试都很喜欢在这里出题,通常会伴随着强制类型转换、二维数组、数组指针等一起考查大家对指针的理解。但是不要怕,也许看完这篇文章你有了新的认识和理解,写的不透彻的地方也希望大家多多指正
理解:指针变量的解引用
我们分下面两步理解:
- 解引用,拿出来的是什么?
- 解引用,根据什么拿出来的?
1. 拿出来的是什么
首先解引用拿出来的就是指针指向的内容,比如指针p指向的是这个地址,*p就是拿出来地址里面的内容;
2. 根据什么拿出来的
指针的类型决定了,对指针解引用的时候有多大的权限(能拿出几个字节)。
#include <stdio.h>
int main()
{int a = 40000;int *p = &a;printf("%d\n", *(char*)p);return 0;
}
本应该是40000的值,咋变成64了?这其实就跟解引用的指针类型有关了,但是这里还涉及了一个知识点是大小端,上面是小端的结果,小端就是低位在低地址,高位在高地址;大端反之,所以会有不同的结果;因为解引用是从低地址开始的;大端结果就应该是0
#include <stdio.h>
int main()
{int a = 40000;int *p = &a;printf("%d\n", *p);return 0;
}
所以这里就是直接解引用了4个字节,只要是涉及多个字节了,取出来的要按照低位还是低位来算,切记不能以为先取出来的就是高位;
理解:指针变量的加法
我们来分这两步理解:
- 指针变量的加法,加的是什么?
- 指针变量的加法,是根据什么来加的?
1. 加的是什么
我们首先来分析指针变量是什么,指针变量是一个地址,那指针变量的加法,实际上就是对这个指针变量代表的地址做加法,也就是向后移动指针变量指向的位置,让指向的地址更高。
2. 根据什么来加
指针变量的加法是根据:指针变量的数据类型实现的;
指针 + n = 指针 + n*指针类型中的除*的类型所占字节
char*就是n
int*就是4n
比如:char*类型
char c = 0;
char *pc = &c;
printf("pc = %p\n", pc);
printf("pc + 1 = %p\n", pc + 1);
我们可以看到pc+1的值是向后移动了1个字节
比如:int*类型
int i = 0;
int *pi = &i;
printf(" pi = %p\n", pi);
printf("pi+1 = %p\n", pi + 1);
此时int类型的pi+1的值是向后移动了4个字节
比如:double*类型
double d = 0;
double *pd = &d;
printf(" pd = %p\n", pd);
printf("pd+1 = %p\n", pd + 1);
此时double类型的pd+1的值是向后移动了8个字节
例题
1. 普通的加法
#include <stdio.h>
int main()
{int arr[5] = {1, 2, 3, 4, 5};int *p = arr;printf("%d\n", *(p + 1));printf("%d\n", p[1]);return 0;
}
答案及解析:2 2
首先p指向的是arr,arr是数组名,代表的是首元素的地址,所以p指向的就是首元素的地址
p数据类型为int*,p+1就是向后移动4*1个字节,到达arr[1]的地址,解引用是取4个字节,取到的就是arr[1];
p既然是首元素地址,那p和arr就没区别,所以p[1] 等价于 arr[1],为2;
2. 包含强制类型转换的加法
#include <stdio.h>
int main()
{int arr[5] = {1, 2, 3, 4, 5};int *p = arr;printf("%d\n", *((char*)p + 1));printf("%d\n", *((short*)p + 2));return 0;
}
答案及解析:0 2
这时候我们必须要用二进制来表示数字,因为这里涉及到了强制类型转换;此时加法和解引用都会受到影响。所以这里的第一个输出语句,是先强制类型转换成char*类型,然后一直是对char*类型的指针进行加法和解引用,这里我一直按小端讲解
而我们的第二个输出语句则是强制转换short*,加法和解引用都是2字节
3. 包含二维数组和数组指针的加法
#include <stdio.h>
int main()
{int arr[2][2] = {{1, 2}, {3, 4}};int (*p)[2] = arr;printf("%d\n", **(p + 1));return 0;
}
在这里首先要知道二维数组名代表的是什么,我们必须清楚一个逻辑
二维数组是一维数组的数组,也就是说可以把二维数组看成存放一维数组的数组;
这样说肯定很抽象,我们看图:
二维数组名代表的是第一行的地址,也就是代表整个第一行,相当于&arr[0],那二维数组名就是一个数组指针了,因为数组指针也是表示的一个数组的地址;所以我们可以定义一个数组指针p = arr;那p + 1,就要慎重了,p的数据类型是int (*)[2],所以p+1,就是移动整个数组的大小,所以p+1 就指向的是arr[1]这个数组,p + 1 = &arr[1],所以解引用一次就是取到了整个数组arr[1],但是*(p + 1) = arr[1],arr[1]是这个二维数组的行,相当于该行这个一维数组的数组名,既然是一维数组的数组名,就是首元素地址,那就是int*类型,再解引用就是解引用4字节,拿到的就是3.
相关文章:
深入理解:指针变量的解引用 与 加法运算
前言 指针变量的解引用和加法运算是非常高频的考点,也是难点,因为对初学者的不友好,这就导致了各大考试都很喜欢在这里出题,通常会伴随着强制类型转换、二维数组、数组指针等一起考查大家对指针的理解。但是不要怕,也许…...
Docker 镜像构建的最佳做法
一、镜像分层 使用docker image history命令,可以看到用于在镜像中创建每个层的命令。 1、 使用docker image history命令查看创建的入门镜像中的层。 docker image history getting-started 您应该得到如下所示的输出: IMAGE CREATED…...
工作上Redis安装及配置
下载redis软件 第一步:解压压缩包 tar -zxvf redis-7.0.14.tar.gz 第二步:移动redis存放目录(结合个人需求而定!) redis-7.0.14:解压后的文件路径 /usr/local:移动后的文件路径 mv redis-7.0.…...
电商项目之Web实时消息推送(附源码)
文章目录 1 问题背景2 前言3 什么是消息推送4 短轮询5 长轮询5.1 demo代码 6 iframe流6.1 demo代码 7 SSE7.1 demo代码7.2 生产环境的应用 (重要) 8 MQTT 1 问题背景 扩宽自己的知识广度,研究一下web实时消息推送 2 前言 文章参考自Web 实时消…...
上机实验四 哈希表设计 西安石油大学数据结构
实验名称:哈希表设计 (1)实验目的:掌握哈希表的设计方法及其冲突解决方法。 (2)主要内容: 已知一个含有10个学生信息的数据表,关键字为学生“姓名”的拼音,给出此表的一…...
Ubuntu22.04 交叉编译mp4V2 for Rv1106
一、配置工具链环境 sudo vim ~/.bashrc在文件最后添加 export PATH$PATH:/opt/arm-rockchip830-linux-uclibcgnueabihf/bin 保存,重启机器 二、下载mp4v2 下载路径:MP4v2 | mp4v2 三、修改CMakeLists.txt 四、执行编译 mkdir build cd buildcmak…...
缓存穿透、击穿、雪崩
缓存穿透: 指的是恶意用户或攻击者通过请求不存在于缓存和后端存储中的数据来使得所有请求都落到后端存储上,导致系统瘫痪。 解决方案: 通常包括使用布隆过滤器或者黑白名单等方式来过滤掉无效请求,以及在应用程序中加入缓存预热…...
(1w字一篇理解透Unsafe类)Java魔法类:Unsafe详解
Java魔法类 Unsafe 文章导读:(约12015字,阅读时间大约1小时)1. Unsafe介绍2. Unsafe创建3. Unsafe功能3.1内存操作3.2 内存屏障3.3 对象操作3.4 数组操作3.5 CAS操作3.6 线程调度3.7 Class操作3.8 系统信息 4. 总结 JUC源码中的并发工具类出现过很多次 …...
Python的正则表达式使用
Python的正则表达式使用 定义使用场景查替换分割 常用的正则表达符号查原字符英文状态的句号点 .反斜杠 \英文的[]英文的()英文的?加号 星号 *英文状态的大括号 {} 案例 定义 正则表达式是指专门用于描述或刻画字符串内在规律的表达式。 使用场景 无法通过切片,…...
Elasticsearch:评估 RAG - 指标之旅
作者:Quentin Herreros,Thomas Veasey,Thanos Papaoikonomou 2020年,Meta发表了一篇题为 “知识密集型NLP任务的检索增强生成” 的论文。 本文介绍了一种通过利用外部数据库将语言模型 (LLM) 知识扩展到初始训练数据之外的方法。 …...
【2023.12.4练习】数据库知识点复习测试
概论 数据表:用于存储现实中数据的联系。 储存信息联系。 字段:又称列,如姓名、年龄、编号等。 记录:又称元组,为数据表中的一行,代表了一个实体的信息。 数据库(DB)࿱…...
【wvp】测试记录
ffmpeg 这是个莫名其妙的报错,通过排查,应该是zlm哪个进程引起的 会议室的性能 网络IO也就20M...
【若依框架实现上传文件组件】
若依框架中只有个人中心有上传图片组件,但是这个组件不适用于el-dialog中的el-form表单页面 于是通过elementui重新写了一个上传组件,如图是实现效果 vue代码 <el-dialog :title"title" v-model"find" width"600px"…...
玩转大数据5:构建可扩展的大数据架构
1. 引言 随着数字化时代的到来,大数据已经成为企业、组织和个人关注的焦点。大数据架构作为大数据应用的核心组成部分,对于企业的数字化转型和信息化建设至关重要。我们将探讨大数据架构的基本要素和原则,以及Java在大数据架构中的角色&…...
【华为数据之道学习笔记】非数字原生企业的特点
非数字原生企业的数字化转型挑战 软件和数据平台为核心的数字世界入口,便捷地获取和存储了大量的数据,并开始尝试通过机器学习等人工智能技术分析这些数据,以便更好地理解用户需求,增强数字化创新能力。部分数字原生企业引领着云计…...
Kubernetes学习笔记-Part.01 Kubernets与docker
目录 Part.01 Kubernets与docker Part.02 Docker版本 Part.03 Kubernetes原理 Part.04 资源规划 Part.05 基础环境准备 Part.06 Docker安装 Part.07 Harbor搭建 Part.08 K8s环境安装 Part.09 K8s集群构建 Part.10 容器回退 第一章 Kubernets与docker Docker是一种轻量级的容器…...
k8s学习
文章目录 前言一、k8s部署方式二、学习k8s的方式今天主要配置k8s环境的方式今天遇到的是一个在k8s进行初始化的方式,但是发现k8s不能正常初始化总是出现错误,或者在错误中有问题的方式,在网上查询挺多资料需要重新启动kub文件,删除…...
测试:JMeter和LoadRunner比较
比较 JMeter和LoadRunner是两款常用的软件性能测试工具,它们在功能和性能上有一定的相似性和差异。下面从几个方面对它们进行比较: 1. 架构和原理: JMeter和LoadRunner的架构和原理基本相同,都是通过中间代理监控和收集并发客户…...
(C语言)通过循环按行顺序为一个矩阵赋予1,3,5,7,9,等奇数,然后输出矩阵左下角的值。
#include<stdio.h> int main() {int a[5][5];int n 1;for(int i 0;i < 5;i ){for(int j 0;j < 5;j ){a[i][j] n;n 2;}}for(int i 0;i < 5;i ){for(int j 0;j < i;j )printf("%-5d",a[i][j]);printf("\n");}return 0; } 运行截图…...
GitHub项目推荐-Deoldify
有小伙伴推荐了一个老照片上色的GitHub项目,看了简介,还不错,推荐给大家。 项目地址 GitHub - SpenserCai/sd-webui-deoldify: DeOldify for Stable Diffusion WebUI:This is an extension for StableDiffusions AUTOMATIC1111 w…...
微前端qiankun示例 Umi3.5
主应用配置(基座) 安装包 npm i umijs/plugin-qiankun -D 配置 qiankun 开启 {"private": true,"scripts": {"start": "umi dev","build": "umi build","postinstall": "…...
熬夜会秃头——beta冲刺Day7
这个作业属于哪个课程2301-计算机学院-软件工程社区-CSDN社区云这个作业要求在哪里团队作业—beta冲刺事后诸葛亮-CSDN社区这个作业的目标记录beta冲刺Day7团队名称熬夜会秃头团队置顶集合随笔链接熬夜会秃头——Beta冲刺置顶随笔-CSDN社区 一、团队成员会议总结 1、成员工作…...
IntelliJ IDEA设置中文界面
1.下载中文插件 2. 点击重启IDE 3.问题就解决啦!...
RTSP流媒体播放器
rtsp主要还是运用ffmpeg来搭建node后端转发到前端,前端再播放这样的思路。 这里讲的到是用两种方式,一种是ffmpeg设置成全局来实现,一种是ffmpeg放在本地目录用相对路径来引用的方式。 ffmpeg下载地址:http://www.ffmpeg.org/do…...
使用正则表达式时-可能会导致性能下降的情况
目录 前言 正则表达式引擎 NFA自动机的回溯 解决方案 前言 正则表达式是一个用正则符号写出的公式,程序对这个公式进行语法分析,建立一个语法分析树,再根据这个分析树结合正则表达式的引擎生成执行程序(这个执行程序我们把它称作状态机&a…...
Maven生命周期
Maven生命周期 通过IDEA工具的辅助,能很轻易看见Maven的九种生命周期命令,如下: 双击其中任何一个,都会执行相应的Maven构建动作,为啥IDEA能实现这个功能呢?道理很简单,因为IDEA封装了Maven提供…...
深度学习(五):pytorch迁移学习之resnet50
1.迁移学习 迁移学习是一种机器学习方法,它通过将已经在一个任务上学习到的知识应用到另一个相关任务上,来改善模型的性能。迁移学习可以解决数据不足或标注困难的问题,同时可以加快模型的训练速度。 迁移学习的核心思想是将源领域的知识迁…...
面试官:说说synchronized与ReentrantLock的区别
程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一波电子书籍资料,包含《Effective Java中文版 第2版》《深入JAVA虚拟机》,《重构改善既有代码设计》,《MySQL高性能-第3版》&…...
数据结构学习笔记——广义表
目录 一、广义表的定义二、广义表的表头和表尾三、广义表的深度和长度四、广义表与二叉树(一)广义表表示二叉树(二)广义表表示二叉树的代码实现 一、广义表的定义 广义表是线性表的进一步推广,是由n(n≥0&…...
为什么每次optimizer.zero_grad()
当你训练一个神经网络时,每一次的传播和参数更新过程可以被分解为以下步骤: 1前向传播:网络对输入数据进行操作,最终生成输出。这个过程会基于当前的参数(权重和偏差)计算出一个或多个损失函数的值。 2计…...
广州网站推广排名/网址大全百度
一、将你要发布的moudle的build.gradle中添加代码,gradle的最后添加 PUBLISH_GROUP_ID com.zzti.fengyongge PUBLISH_ARTIFACT_ID imagepicker PUBLISH_VERSION 1.0 apply from: https://raw.githubusercontent.com/blundell/release-android-library/master/and…...
网站建设与维护费用/无锡网站优化
?《计算机科学导论》考试大纲一、考试大纲的性质《计算机科学导论》是报考农业工程与信息技术领域农业硕士同等学历的加试科目。为帮助考生明确考试复习范围和有关要求,特制定本考试大纲,该大纲适用于报考北京农学院农业硕士学位的考生。二、…...
做网站天通苑/网络营销策划书
数据插值方法x测试结果2.拟合方法Polyfit Function[p,s]polyfit(x,y,n);返回多项式系数向量p和矩阵s,s与polyval函数一起用时,可以得到预测值的误差估计。[p,s,mu]polyfit(x,y,n);返回多项式的系数,利用该函数进行多项式曲线拟合评价。Polyva…...
wordpress 判断语言/泉州排名推广
IP核:美国著名的Dataquest咨询公司将半导体产业的IP定义为“用于ASIC或FPGA中的预先设计好的电路功能模块”。IP主要分为软IP、固IP和硬IP。软IP是用Verilog/VHDL等硬件描述语言描述的功能块,但是并不涉及用什么具体电路元件实现这些功能。固IP是完成了综…...
建定制营销型网站/互联网营销师证书
CentOS7 特点总结CentOS7 特点总结1.runlevel/etc/inittab 中开启启动模式已失效,但还可以通过命令 init 0/1/2/3/4/5/6进行设置7版本中更新为systemctl set-default graphical.target (设置图形界 启动),实际是在/etc/systemd/system/ 目录下创建指向/u…...
wordpress logged in/seo诊断方案
前文回顾事务处理的四种分离水平(隔离级别)分离水平的设置注意事项 非提交读取(脏读)不可重复读取幻象读取总结: 前文回顾 在上篇博文史上最简单MySQL教程详解(进阶篇)之锁与事务处理分离水平&…...