当前位置: 首页 > news >正文

深入理解 C/C++ 指针

深入理解 C++ 指针:指针、解引用与指针变量的详细解析

在这里插入图片描述

前言

在 C++ 编程语言中,指针 是一个非常强大且重要的概念。对于初学者来说,指针往往会让人感到困惑不解。本文将通过形象的比喻,帮助大家深入理解指针、解引用与指针变量的概念,带你一步步掌握指针的使用。

什么是指针?

简单来说,指针 是一个保存了内存地址的变量。普通变量存储的是数据本身,而指针存储的是某个变量的内存地址。可以通过指针访问到该内存地址中存储的数据。

形象比喻:

想象一下,你有一个朋友要去你家找你:

  • 你家的地址:就像指针,它不是你本人,但指向了你家,告诉别人如何找到你。
  • 你本人:就是存储在内存中的实际数据,当有人通过你家的地址找到你时,就等于通过指针访问到了内存中的实际数据。

代码示例:

int a = 5;       // 变量 a 存储的是数值 5
int *p = &a;     // 指针 p 保存了变量 a 的地址

在这个例子中,a 是一个普通变量,存储了值 5,而 p 是一个指针,它保存了变量 a 的内存地址。也就是说,p 知道 a 存储在内存的什么位置。

解引用是什么?

当我们知道了变量的地址后,如何通过这个地址去访问实际存储的数据呢?这就需要用到解引用

解引用 是指通过指针访问指针所指向的内存中的数据。解引用操作符是星号(*)。当你对指针使用 * 操作时,表示你要访问指针指向的那个变量的值。

形象比喻:

  • 通过朋友知道了你家的地址,但要真正找到你,需要按照这个地址走到你家门口,敲门,看到你本人。这就是解引用的过程。

代码示例:

int a = 5;       // 变量 a 存储的是数值 5
int *p = &a;     // 指针 p 保存了变量 a 的地址cout << *p;      // 输出 a 的值,通过解引用访问 a

在上面的例子中,*p 代表通过指针 p 访问 a 的值,所以 cout 将会输出 5

总结:

  • p 保存的是 a 的地址(指针)。
  • *p 解引用 p,表示我们访问了 a 的值(实际数据)。

指针与普通变量的区别

类型描述类比
普通变量存储的是数据本身家里的物品
指针存储的是某个变量的内存地址你家的地址
指针解引用通过指针找到并访问该地址存储的值朋友找到你本人

普通变量可以直接操作存储的数据,而指针存储的是地址,你需要通过解引用操作符 * 来访问指针所指向的数据。

代码示例一:交换两个整数的最大最小值

示例一代码:

#include<iostream>
using namespace std;int main() {int *p1, *p2, *p, a, b; cout << "请输入两个整数" << endl;cin >> a >> b;  // 输入两个整数p1 = &a;       // p1 指向 ap2 = &b;       // p2 指向 bif (a < b) {   // 交换 p1 和 p2 的指向,使得 p1 始终指向较大的值p = p1;   p1 = p2;p2 = p;}cout << "a=" << a << "b=" << b << endl;cout << "max=" << *p1 << " min=" << *p2 << endl; // 输出最大值和最小值return 0;
}

示例一结果:

请输入两个整数
45 78
a=45 b=78
max=78 min=45
示例一解释:
  • 在这个例子中,我们通过 p1p2 这两个指针分别指向变量 ab。程序判断 a 是否小于 b,如果是,则交换 p1p2 的指向。最终,p1 始终指向较大的值,p2 指向较小的值。通过解引用 *p1*p2,我们分别得到了 ab 的最大值和最小值。

  • 关键点:这个示例展示了如何使用指针交换两个变量的指向,而不需要实际交换变量 ab 的值。

代码示例二:交换两个整数的值

示例二代码:

#include<iostream>
using namespace std;int main() {int *p1, *p2, a, b; cout << "请输入两个整数" << endl;cin >> a >> b;  // 输入两个整数p1 = &a;       // p1 指向 ap2 = &b;       // p2 指向 bif (a < b) {   int p;p = *p1;   // 将 p1 指向的值赋给临时变量 p*p1 = *p2; // 将 p2 指向的值赋给 p1 所指向的地址(a)*p2 = p;   // 将临时变量 p 的值赋给 p2 所指向的地址(b)}cout << "a=" << a << "b=" << b << endl;cout << "max=" << *p1 << " min=" << *p2 << endl; // 输出最大值和最小值return 0;
}

示例二结果:

请输入两个整数
45 78
a=78 b=45
max=78 min=45
示例二解释:
  • 在这个例子中,我们不仅仅交换了指针指向的地址,还交换了 ab 这两个变量的值。首先,通过 p1p2 分别指向 ab。然后,使用一个临时变量 p 存储 p1 所指向的值(即 a 的值),接着将 p2 所指向的值赋给 p1,再将临时变量 p 的值赋给 p2。最终实现了 ab 的值交换。

  • 关键点:此示例展示了如何通过解引用指针来实际交换两个变量的值。

指针与解引用的区别和联系

通过上述两个例子可以看出:

  1. 示例一中,我们交换的是指针的指向,也就是说 p1p2 交换后,指向不同的变量,但 ab 的值并没有改变。

  2. 示例二中,我们实际交换了指针指向的变量的值,通过解引用 *p1*p2,将 ab 的值进行了交换。

两者的核心区别在于,示例一中的指针仅仅是交换了指向的对象,而示例二通过解引用操作符 * 实现了对象本身值的交换。
在这里插入图片描述

常见错误

初学者在使用指针时容易犯一些常见错误,下面是两个需要特别注意的地方:

  1. 未初始化指针:在给指针赋值之前,指针变量是未初始化的,它可能指向一个随机的内存地址,这可能会导致程序崩溃。

    int *p;       // 没有初始化
    cout << *p;   // 错误!未初始化的指针解引用
    

    解决方法:指针在使用之前一定要初始化。比如可以让指针指向某个已知变量,或者将其初始化为 nullptr

    int *p = nullptr;   // 指针初始化为 nullptr
    
  2. 野指针:当指针指向的内存已经

被释放或无效时,指针就变成了“野指针”,对这种指针的操作会导致不可预期的结果,甚至崩溃。
cpp int *p = new int(10); // 动态分配内存 delete p; // 释放内存 cout << *p; // 错误!访问已经释放的内存

结束语

指针是 C++ 中非常强大的工具,能够让你直接操作内存,从而实现更灵活和高效的代码。但同时,指针的使用也伴随着一定的风险和复杂性。理解指针、指针变量和解引用是迈向高级编程的关键一步,希望本文的讲解和比喻能帮助你更好地掌握这一概念。

欢迎在评论区讨论你对指针的疑惑和心得!


这篇博客通过形象的比喻和代码示例,帮助读者更好地理解指针和解引用的概念。如果你觉得这篇博客对你有帮助,不妨分享给更多的朋友!在这里插入图片描述

相关文章:

深入理解 C/C++ 指针

深入理解 C 指针&#xff1a;指针、解引用与指针变量的详细解析 前言 在 C 编程语言中&#xff0c;指针 是一个非常强大且重要的概念。对于初学者来说&#xff0c;指针往往会让人感到困惑不解。本文将通过形象的比喻&#xff0c;帮助大家深入理解指针、解引用与指针变量的概念…...

有什么方法可以保护ppt文件不被随意修改呢?

在工作或学习中&#xff0c;我们常常需要制作powerpoint演示文稿&#xff0c;担心自己不小心改动了或者不想他人随意更改&#xff0c;我们可以如何保护PPT呢&#xff1f;下面小编就来分享两个常用的方法。 方法一&#xff1a;为PPT设置打开密码 为PPT设置打开密码是最直接有效…...

[C#]项目中如何用 GraphQL 代替传统 WebAPI服务

在现代应用程序开发中&#xff0c;传统的 WebAPI 通常使用 RESTful 设计风格&#xff0c;然而近年来 GraphQL 作为一种新的 API 查询语言逐渐获得广泛应用。GraphQL 允许客户端精确地查询所需的数据&#xff0c;减少了过度请求和不足请求的问题。本文将详细讨论在项目中用 Grap…...

对后端返回的日期属性进行格式化(扩展 Spring MVC 的消息转换器)

格式化之前 格式化之后&#xff1a; 解决方式 方式一 在属性中加上注解&#xff0c;对日期进行格式化 JsonFormat(pattern "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;//JsonFormat(pattern &quo…...

踩坑记录-用python解析php Laravel8生成的jwt token一直提示 Invalid audience

import jwtdef token_required(token):with open(storage/oauth-public.key, r) as f:public_key f.read()try:# 尝试使用当前算法解码 token&#xff0c;同时指定受众decoded jwt.decode(token, public_key, algorithms[RS256], options{"verify_aud": False})# p…...

使用IOT-Tree Server制作一个边缘计算设备(Arm Linux)

最近实现了一个小项目&#xff0c;现场有多个不同厂家的设备&#xff0c;用户需要对此进行简单的整合&#xff0c;并实现一些联动控制。 我使用了IOT-Tree Server这个软件轻松实现了&#xff0c;不外乎有如下过程&#xff1a; 1&#xff09;使用Modbus协议对接现有设备&#…...

(JAVA)B树和B+树的实现原理阐述

1. B 树 2-3树中&#xff0c;一个节点最多能有两个key&#xff0c;它的实现红黑树中适用对链接染色的方式去表达这两个key。下面将学习另一种树形结构B树&#xff0c;这种数据结构中&#xff0c;一个节点允许多余两个key的存在。 B树是一种树状数据结构&#xff0c;它能够存储…...

JC系列CAN通信说明

目录 一、CAN协议二、指令格式三、通信接线3.1、一对一通信3.2、组网通信 四、寄存器定义五、指令说明4、读取电源电压5、读取母线电流6、读取实时速度8、读取实时位置10、读取驱动器温度11、读取电机温度12、读取错误信息32、设定电流33、设定速度35、设定绝对位置37、设定相对…...

Ubuntu22——安装并配置局域网文件共享系统Samba

我们将共享目录设置为 /home/takway/share。以下是基于这个新目录的详细步骤&#xff1a; 在Ubuntu上安装并配置Samba 更新系统包列表 打开终端&#xff0c;执行以下命令来确保你的包列表是最新的&#xff1a; sudo apt update安装Samba 安装Samba及其相关工具&#xff1a; sud…...

HTML CSS 基础

HTML & CSS 基础 HTML一、HTML简介1、网页1.1 什么是网页1.2 什么是HTML1.3 网页的形成1.4总结 2、web标准2.1 为什么需要web标准2.2 Web 标准的构成 二、HTML 标签1、HTML 语法规范1.1基本语法概述1.2 标签关系 2、 HTML 基本结构标签2.1 第一个 HTML 网页2.2 基本结构标签…...

Nginx 使用 GeoIP 模块阻止特定国家 IP 地址的最佳实践

一、概述 为什么要阻止特定国家的 IP 地址&#xff1f; 在全球化的互联网上&#xff0c;网站和服务器可能会面对来自不同国家和地区的用户流量。虽然大多数情况下&#xff0c;我们希望网站能为全球用户提供服务&#xff0c;但在某些特定场景下&#xff0c;阻止来自特定国家的…...

vue3 + vite + cesium项目

GitHub - tingyuxuan2302/cesium-vue3-vite: 项目基于 vue3 vite cesium&#xff0c;已实现常见三维动画场&#xff0c;欢迎有兴趣的同学加入共建&#xff0c;官网服务器相对拉胯&#xff0c;请耐心等候...https://github.com/tingyuxuan2302/cesium-vue3-vite/tree/github...

DR模式 LVS负载均衡群集

DR模式 LVS负载均衡群集 部署共享存储关闭防火墙和核心防护下载&#xff0c;开启nfs服务创建共享文件夹和测试用的静态网页文件编辑nfs配置文件发布共享查看共享 配置 tomcat 服务器关闭防火墙和核心防护安装tomcat配置 tomcat 多实例 配置 nginx 服务器关闭防火墙和核心防护配…...

mysql复制表结构和数据

1.实例 #复制一张和test 一摸一样的表结构 CREATE TABLE test_one like test#往复制的表结构中复制数据 INSERT INTO test_one SELECT * FROM test#两者一起使用相当于 cv大法2.总结 完全实现了表结构和数据的复制&#xff0c;但是两条sql 得分两步执行 2.1 复制表结构 #复制…...

MFC扩展库BCGControlBar Pro v35.1新版亮点:改进网格控件性能

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v35.1已全新发布了&#xff0c;这个版本改进网格控件的性能、增强工具栏编辑器功能等。 …...

Python列表操作详解

1 列表的基本概念 在Python中&#xff0c;列表是一种非常常用的数据结构&#xff0c;它可以存储任意类型的元素&#xff0c;并且支持多种操作。下面将详细介绍Python列表的各种操作。 2列表的操作方法 2.1创建列表 Python可以直接使用方括号[]来创建一个空列表。 示例&am…...

畅捷通T+对接聚水潭成功实施案例

在当今竞争激烈的商业环境中&#xff0c;企业数字化转型已成为提升竞争力的关键。广东某实业有限公司的数字化规划&#xff0c;目前财务系统使用的畅捷通T&#xff0c;电商系统使用的聚水潭。目前两个系统数据割裂导致各个部门的协同效率低下。通过借助轻易云数据集成平台&…...

leetcode-312. 戳气球

题目描述 有 n 个气球&#xff0c;编号为0 到 n - 1&#xff0c;每个气球上都标有一个数字&#xff0c;这些数字存在数组 nums 中。 现在要求你戳破所有的气球。戳破第 i 个气球&#xff0c;你可以获得 nums[i - 1] * nums[i] * nums[i 1] 枚硬币。 这里的 i - 1 和 i 1 代…...

程序设计基础I-实验7 函数(编程题)

7-1 sdut- C语言实验—计算表达式 计算下列表达式值&#xff1a; 输入格式: 输入x和n的值&#xff0c;其中x为非负实数&#xff0c;n为正整数。 输出格式: 输出f(x,n)&#xff0c;保留2位小数。 输入样例: 3 2输出样例: 在这里给出相应的输出。例如&#xff1a; 2.00 …...

使用3080ti配置安装blip2

使用3080ti运行blip2的案例 本机环境&#xff08;大家主要看GPU&#xff0c;ubuntu版本和cuda版本即可&#xff09;&#xff1a;安装流程我最后安装的所有包的信息&#xff08;python 3.9 &#xff09;以供参考&#xff08;environment.yml&#xff09;&#xff1a; 本机环境&a…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...