C 语言指针学习笔记

C 语言中,指针存储的是变量的内存地址!!!

要彻底理解指针,首先要理解 C 语言中变量的存储本质,也就内存。

内存编址与内存空间

计算机的内存是一块用于存储数据的空间,由一系列连续的存储单元组成。
如下图所示,每个单元格都表示 1 个 bit,8 个 bit 为一组,称为 byte;byte 是计算机中作为内存寻址的最小单元
1 byte = 8 bit

图1

可以理解为,计算机给每个 byte 一个编号,这个编号就是内存的地址。
计算机中,每个 byte 的编号都是唯一的,从而保证了计算机可以通过每个编号访问到唯一确定的 byte。

图2

因为内存中,每个 byte 都有一个唯一的编号,所以编号的范围也就决定了计算机中可以寻址的内存空间。
所有编号连起来就是内存的地址空间。

变量存放

C++ 或 C 中可以如下定义向量

int a = 999;
char c = 'c';

当定义一个变量时,实际上是向内存申请了一块空间来存放变量(不同的数据类型,申请的空间是不同的)
int 类型占 4 个字节,在计算机中使用补码保存。
999 的补码为:0000 0011 1110 0111

图3

按照大端的存储方式,上述变量 a 会在内存中,如上图方式保存;如果是按照小端的存储方式,会如下图方式保存

图4

大端:高位字节放在内存的低地址的存储方式
小端:低位字节放在内存的低地址的存储方式

对于 float 、 char 、数组、指针、结构体、对象等类型的数据实际上也是一样的,需要先转换为补码,再按照大端或者小端的方式,依次将字节写入到内存单元中

指针

定义一个变量实际上就是向计算机申请了一块内存存放数据,这个地址可以通过运算符 & 得到(虚拟内存地址,并不是实际物理地址),得到的值就是变量所占内存块的起始地址,在 C 语言中通过 指针 这一概念来表示这个地址。

int * pa = &a;

pa 中存储的就是变量 a 的地址,也称为指向 a 的指针

所以,指针的本质,就是变量的内存首地址,即一个 int 类型的整数

那么问题来了,如果指针都是一个 int 类型的整数,为什么会有各种数据类型的指针呢?

pa 中存储的是变量 a 的内存地址,通过这个指针地址得到 a 的值的操作,称为 解引用*pa

由于指针存储的只是变量内存的首地址,对于不同变量,其所占内存空间是不同的,如果不能把所有数据从内存空间取出,那么解引用得到的数据就会出错,而指针的类型,则可以帮助编译器判断,从首地址开始取多少字节的数据,从而保证解引用的正确

图5

pa 指针本身也是一个变量,在内存中占有一定的空间

案例
float f = 1.0;
short c = *(short*)&f;

tu 6

从内存层面而言,f 没有发生任何变化
第二行代码,只是把 f 的前两个 byte 取出来,然后按照 short 指针的方式解引用,最后赋值给 c

那么,对于下面两行代码呢?

short c = 1;
float f = *(float*)&c;

(float*)&c 会让我们从 c 的首地址开始取四个字节,然后按照 float 的编码方式去解释
但是 c 语言 中 short 类型只占两个字节,那肯定会访问到相邻后面两个字节,这时候就发生了内存访问越界
当然,如果只是读,大概率是没问题的,但是,如果向这个区域写入新值

*(float*)&c = 1.0;

那么就可能发生 coredump,也就是访存失败
另外,就算是不会 coredump,这种也会破坏这块内存原有的值,因为很可能这是是其它变量的内存空间,而我们去覆盖了人家的内容,肯定会导致隐藏的 bug。

多级指针

多级指针,就是指针的指针的指针的指针…
实际上,多级指针只是一个为了方便我们理解和表达的逻辑概念

同样一个内存,如果存放的是别的变量的地址,就是指针;如果存放的是实际内容,就是变量;当存放的是别的指针的地址,就是指针的指针,依此类推,可以得到任意多级指针

指针本身也是一个变量,需要内存取存储,指针也有自己的地址
指针内存存储的是它所指向变量的地址

int a;
int *pa = &a;   // 指针
int **ppa = &pa;  // 二级指针
int ***pppa = &ppa;  // 三级指针

图7

如上图所示,pppa 就是三级指针,ppa 就是二级指针,pa 就是指针

对于 int ** a 可以把它分为两部分看,int **a*a 表示 a 是一个指针变量,int* 则表示 a 存放的是 int * 型变量的地址,对于其他多级指针都可以如此类推

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python 反编译Il2Cpp APK

引入 https://github.com/Perfare/Il2CppDumper/ 实现 开源的Ii2Cpp Dumper可以帮助我们将So和globalmetadata.dat文件反编译出 Assembly-CSharp.dll 本博客教程可以帮助我们直接拖入APK反编译出来 调用方式 两种 第一种 拖入后回车运行 第二种 放入运行的根目录下 源码 i…

手动搭建koa+ts项目框架(日志篇)

文章目录 前言一、安装koa-logger二、引入koa-logger并使用总结如有启发,可点赞收藏哟~ 前言 本文基于手动搭建koats项目框架(路由篇)新增日志记录 一、安装koa-logger npm i -S koa-onerror and npm i -D types/koa-logger二、引入koa-lo…

IoTDB JavaAPI

文章目录 使用样例Java使用样例 官方已经给出了相关使用Demo,下载地址为: https://github.com/apache/iotdb 直接拉取相对应版本的源码 使用样例 Java使用样例 代码位置 iotdb/example/session/src/main/java/org/apache/iotdb/SessionExample.java iotdb/exa…

借助 AI 梳理知识:Quivr 帮你打造第二大脑 | 开源日报 No.103

fastlane/fastlane Stars: 37.8k License: MIT fastlane 是一个用于 iOS 和 Android 开发人员自动化繁琐任务的工具,如生成屏幕截图、处理配置文件和发布应用程序。 可以轻松地生成屏幕截图处理证书文件发布应用程序通过命令行快速执行操作 DrKLO/Telegram Sta…

血的教训,BigDecimal踩过的坑

很多人都用过Java的BigDecimal类型,但是很多人都用错了。如果使用不当,可能会造成非常致命的线上问题,因为这涉及到金额等数据的计算精度。 首先说一下,一般对于不需要特别高精度的计算,我们使用double或float类型就可…

【lesson7】数据类型之string类型

文章目录 数据类型分类string类型set类型测试 enum类型测试 string类型的内容查找找所有女生(enum中)找爱好有游泳的人(set中)找到爱好中有足球和篮球的人 数据类型分类 string类型 set类型 说明: set:集…

nrfutil工具安装

准备工作,下载相关安装包 链接:https://pan.baidu.com/s/1LWxhibf8LiP_Cq3sw0kALQ 提取码:2dlc 解压后,分别安装以下安装包 在C盘下创建目录nordic_tools,并将nrfutil复制到刚创建的目录下 环境变量path下添加C:\nor…

【截图版本】Linux常用指令详解

———————————————— 版权声明:本文为CSDN博主「小呆瓜历险记」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_58963318/article/details/134713282

ProroBuf C++笔记

一.什么是protobuf Protocol Buffers是Google的⼀种语⾔⽆关、平台⽆关、可扩展的序列化结构数据的⽅法,它可⽤于(数据)通信协议、数据存储等。Protocol Buffers 类⽐于XML,是⼀种灵活,⾼效,⾃动化机制的结…

51单片机应用从零开始(十一)·数组函数、指针函数

51单片机应用从零开始(九)数组-CSDN博客 51单片机应用从零开始(十)指针-CSDN博客 目录 1. 用数组作函数参数控制流水花样 2. 用指针作函数参数控制 P0 口 8 位 LED 流水点亮 1. 用数组作函数参数控制流水花样 要在51单片机中…

0012Java安卓程序设计-ssm记账app

文章目录 **摘要**目 录系统设计5.1 APP端(用户功能)5.2后端管理员功能模块开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅🐧裙:776871563 摘要 网络的广泛应用给生活带来了十分的便利。所以把记账管理与现在网络相…

GaussDB数据库语法及gsql入门

一、GaussDB数据库语法入门 之前我们讲了如何连接数据库实例,那连接数据库后如何使用数据库呢?那么我们今天就带大家了解一下GaussDB,以下简称GaussDB的基本语法。 关于如何连接数据库,请戳这里。 学习本节课程之后&#xff0c…

【金华模式】双龙旅游引燃露营设计和文旅产融合新方式

(中国国际教育电视台 黎明)金华双龙风景旅游区位于浙江省金华市北郊的金华山麓,是一处融自然山水、溶洞群景观、科普探险、康体休闲、避暑度假、观光朝圣于一体的景区。旅游区人文积淀深厚,道、儒、释文化兼收并蓄,东汉…

大语言模型有什么意义?亚马逊训练自己的大语言模型有什么用?

近年来,大语言模型的崭露头角引起了广泛的关注,成为科技领域的一项重要突破。而在这个领域的巅峰之上,亚马逊云科技一直致力于推动人工智能的发展。那么,作为一家全球科技巨头,亚马逊为何会如此注重大语言模型的研发与…

Blender学习:走路机器人,骨骼绑定

文章目录 建模骨骼创建骨骼绑定 教程地址:八个案例教程带你从0到1入门blender【已完结】 建模 1 做头:新建立方体,Ctrl2细分并应用,进入编辑模式,删除一半点,然后添加镜像修改器,开启范围限制…

软件测试20个基础面试题及答案

什么是软件测试? 答案:软件测试是指在预定的环境中运行程序,为了发现软件存在的错误、缺陷以及其他不符合要求的行为的过程。 软件测试的目的是什么? 答案:软件测试的主要目的是保证软件的质量,并尽可能…

python socket编程9 - PyQt6界面实现UDP server/client 多客户端通讯的例子

本篇实现 UDP server和client多客户端通讯的例子。 在UDP单机通讯的基础上进行重构,实现UDP server与多个 client通讯的例子。 创建两个 PyQt6的项目,一个作为UDP server 项目,另一个作为UDP client项目。 一、效果图 1、udp server界面 …

在线学习平台-课程分页、用户管理、教师查询

在线学习平台------手把手教程👈 用户管理 添加功能增强 新增属性 若依里的用户模块(SysUser)是没有课程这一属性的,要实现我们自己的课程分页查询功能 这个位置传入的实体类SysUser要加上classId,记得加上get、set方法 更改sql语句 ctrl 鼠标左键不断点进去…

使用Gson完成java对象的序列化和反序列化

一、前言:json是什么?,Gson是什么? 1.JSON(javaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。 2.Gson 是Google提供的用来在java对象…

Nextui使用

安装和使用 https://nextui.org/docs/frameworks/nextjs 自定义主题 https://nextui.org/docs/customization/customize-theme // tailwind.config.js const {nextui} require("nextui-org/react");/** type {import(tailwindcss).Config} */ module.exports {…