C++:指针(Pointers)

article/2025/6/21 19:22:30

目录

什么是指针?

为什么需要指针?

1. 访问堆(Access Heap)

2. 资源管理(Resource Management) 

3. 参数传递(Parameter Passing)

 如何声明和使用指针?

如何利用指针访问堆内存? 

1. 使用 malloc 访问堆内存 

 2. 使用 new 访问堆内存


什么是指针?

指针是一个地址变量,用于存储数据的地址,而不是数据本身。

普通变量是数据变量,但指针是地址变量,用于间接访问数据。

所以,我们提出问题:为什么我们需要间接访问数据?

为什么需要指针?

1. 访问堆(Access Heap)

程序运行时,RAM(随机存取存储器,Random Access Memory)分为三部分:

  • 代码部分(Code Section):存储程序的机器码(Machine Code),即编译后的指令。

  • 栈(Stack):存储局部变量(Local Variables,如函数内的int、char),由系统自动分配和释放。栈大小有限,变量生命周期随函数作用域结束。

  • 堆(Heap):更大的内存区域,程序员通过动态分配(Dynamic Allocation)使用,生命周期由程序员控制。

程序可以直接访问的部分是代码部分和栈内存,无法直接使用堆内存。所以说,堆内存在程序之外,那么该如何访问堆内存呢?这时就需要用到了指针。 

堆内存的分配需要通过new操作符,分配后返回内存地址,存储在指针中。例如:

int* ptr = new int; // 在堆上分配一个整数,ptr存储其地址
*ptr = 10;         // 通过指针访问堆内存,存储值10

没有指针,程序无法操作堆内存,也就无法实现动态数据结构或存储大块数据。 

2. 资源管理(Resource Management) 

程序运行在内存中,但需要访问外部资源,如文件(Files)、硬盘(Hard Disk)、互联网(Internet)(如网络套接字Socket)。这些资源位于程序外部,操作系统(Operating System)管理它们,程序无法直接访问其内容。

外部资源(如文件、硬盘、互联网连接)由操作系统分配句柄或内存地址,程序通过指针访问这些句柄。例如: 

FILE* fp = fopen("data.txt", "r"); // 打开文件,fp指向文件句柄
if (fp != nullptr) {// 通过fp操作文件fclose(fp); // 关闭文件,释放资源
}

这里,fp是一个指针,指向操作系统分配的文件句柄(File Handle),程序通过它读写文件。

外部资源(如文件、硬盘、互联网)在程序外部,操作系统通过句柄或地址管理,指针是程序访问这些资源的唯一途径。指针通过地址共享资源,提高效率。

 

3. 参数传递(Parameter Passing)

  • C++默认使用值传递(Pass by Value),传递数据副本,函数内修改不影响原数据。复制大对象(如数组、结构体)效率低,且无法修改调用者的变量。

  • 函数需要高效传递数据,有时需要修改原数据,或表示“无数据”状态。

指针支持按地址传递(Pass by Pointer),让函数直接操作调用者的内存。例如:

void swap(int* a, int* b) {int temp = *a; // 访问a的内存*a = *b;       // 修改a的内存*b = temp;     // 修改b的内存
}
int main() {int x = 10, y = 20;swap(&x, &y);  // 传递x和y的地址// x现在是20,y是10
}

 如何声明和使用指针?

这部分不再赘述,详细教程可以参考下面的学习网站: 

C++ 指针 | 菜鸟教程 

如何利用指针访问堆内存? 

1. 使用 malloc 访问堆内存 

malloc(Memory Allocation)是C语言的动态内存分配函数,C++中仍然可用,位于<cstdlib>头文件中。它分配原始内存,不初始化,适合C风格编程。

首先声明一个指针,指定指向的数据类型。

分配堆内存:

ptr = (int*)malloc(sizeof(int)); // 分配一个整数大小的内存
  • 使用malloc分配指定大小的内存,返回void*类型地址,需强制转换为目标类型。

  • 语法:ptr = (type*)malloc(size);

  • sizeof(int):计算整数类型的大小

  • (int*):将void*转换为int*。

访问内存(解引用,Dereference):

  • 通过*操作符访问或修改指针指向的内存。

if (ptr != nullptr) {*ptr = 42; // 存储值42std::cout << *ptr; // 输出:42
}

释放内存:

  • 使用free释放堆内存,防止内存泄漏(Memory Leak)。

free(ptr); // 释放内存
ptr = nullptr; // 避免悬空指针(Dangling Pointer)

 2. 使用 new 访问堆内存

 new是C++的动态内存分配操作符,位于<new>头文件中(通常无需显式包含)。它分配内存并初始化(对于类会调用构造函数),是C++的首选方式。

首先声明一个指针,指定指向的数据类型。

分配堆内存:

  • 使用new分配内存,返回目标类型的指针,无需强制转换。

ptr = new int; // 分配一个整数的内存

访问内存:

  • 通过*操作符访问或修改内存。

*ptr = 100; // 存储值100
std::cout << *ptr; // 输出:100

释放内存:

  • 使用delete释放内存,防止内存泄漏。

delete ptr; // 释放内存
ptr = nullptr; // 避免悬空指针

分配动态数组:

  • 使用new[]分配连续内存,适合动态数组。

int* arr = new int[5]; // 分配5个整数的数组
for (int i = 0; i < 5; i++) {arr[i] = i + 1; // 填充数组:1, 2, 3, 4, 5
}
delete[] arr; // 释放数组内存
arr = nullptr;

关键点

  • new自动匹配指针类型,无需强制转换,比malloc更安全。

  • 对于类,new会调用构造函数,delete调用析构函数,适合面向对象编程。

  • 数组用new[]分配,delete[]释放,匹配使用以避免未定义行为。


http://www.hkcw.cn/article/oyNkKtsUoU.shtml

相关文章

Acrobat DC v25.001 最新专业版已破,像word一样编辑PDF!

在数字化时代&#xff0c;PDF文件以其稳定性和通用性成为了文档交流和存储的热门选择。无论是阅读、编辑、转换还是转曲&#xff0c;大家对PDF文件的操作需求日益增加。因此&#xff0c;一款出色的PDF处理软件不仅要满足多样化的需求&#xff0c;还要通过简洁的界面和强大的功能…

RabbitMQ 高级特性

准备工作 1. 创建 Spring 项目 2. 引入依赖 3.修改配置文件 RabbitMQ官网 AMQP 0-9-1 Protocol Extensions | RabbitMQ 消息确认 消息确认机制 生产者发送消息,到达消费者后,可能会有以下情况: 1.消息处理成功 2.消息处理异常 RabbitMQ 向消费者发送消息之后,会把消息删除…

机器学习:欠拟合、过拟合、正则化

本文目录&#xff1a; 一、欠拟合二、过拟合三、拟合问题原因及解决办法四、正则化&#xff1a;尽量减少高次幂特征的影响&#xff08;一&#xff09;L1正则化&#xff08;二&#xff09;L2正则化&#xff08;三&#xff09;L1正则化与L2正则化的对比 五、正好拟合代码&#xf…

电路学习(二)之电容

电容的基本功能是通交流隔直流、存储电量&#xff0c;在电路中可以进行滤波、充放电。 1.什么是电容&#xff1f; &#xff08;1&#xff09;电容定义&#xff1a;电容器代表了器件存储电荷的能力&#xff0c;通俗来理解是两块不连通的导体与绝缘的中间体组成。当给电容充电时…

第十二节:第二部分:集合框架:Collection集合的遍历方式:迭代器、增强for循环、Lambda、案例

迭代器遍历集合 增强for循环遍历集合 Lambda表达式遍历集合 代码&#xff1a; 代码一&#xff1a;使用迭代器遍历集合 package com.itheima.day18_Collection;import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; // //使用迭代器遍历集合…

任务18:时间序列的模型

任务描述 知识点&#xff1a; 移动平均法指数平滑法ARIMA模型 重 点&#xff1a; 指数平滑法ARIMA模型 内 容&#xff1a; 创建时间序列索引绘制时间序列图形处理时间序列数据建立时间序列模型模型效果评估应用模型预测 任务指导 1. 移动平均法 移动平均法&#xff…

Java研学-MongoDB(一)

一 MongoDB 简介 MongoDB是一种高性能、开源的NoSQL数据库&#xff0c;采用面向文档的存储模型&#xff0c;以BSON&#xff08;Binary JSON&#xff09;格式存储数据&#xff0c;具有灵活的数据模型、强大的扩展性和丰富的功能特性&#xff0c;广泛应用于各类现代应用程序的数据…

【LLM相关知识点】 LLM关键技术简单拆解,以及常用应用框架整理(二)

【LLM相关知识点】 LLM关键技术简单拆解&#xff0c;以及常用应用框架整理&#xff08;二&#xff09; 文章目录 【LLM相关知识点】 LLM关键技术简单拆解&#xff0c;以及常用应用框架整理&#xff08;二&#xff09;一、市场调研&#xff1a;业界智能问答助手的标杆案例1、技术…

自动化立体仓库WCS的设计与实现

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。欢迎大家使用我们的仓储物流技术AI智能体。 新书《智能物流系统构成与技术实践》 新书《智能仓储项目出海-英语手册&#xff0c;必备&#xff01;》 完整版文件和更多学习资料&#xf…

2025年5月18日蓝桥stema省选拔赛编程题答案解析

题目&#xff1a;水龙头 时间限制&#xff1a;C/C 语言 1000MS&#xff1b;其他语言 3000MS 内存限制&#xff1a;C/C 语言 65536KB&#xff1b;其他语言 589824KB 题目描述&#xff1a; 小明在 0 时刻&#xff08;初始时刻&#xff09;将一个空桶放置在漏水的水龙头下。已知桶…

基于开源AI大模型AI智能名片S2B2C商城小程序源码的销售环节数字化实现路径研究

摘要&#xff1a;在数字化浪潮下&#xff0c;企业销售环节的转型升级已成为提升竞争力的核心命题。本文基于清华大学全球产业研究院《中国企业数字化转型研究报告&#xff08;2020&#xff09;》提出的“提升销售率与利润率、打通客户数据、强化营销协同、构建全景用户画像、助…

使用 HTML + jsmind 实现在线思维导图

在日常工作和学习中&#xff0c;思维导图是一种非常有效的可视化工具&#xff0c;可以帮助我们梳理思路、规划任务、整理知识结构。本文将带你一步步了解如何使用 HTML 和 jsmind 实现一个基础的在线思维导图应用。 效果演示 项目概述 本项目主要包含以下核心功能&#xff1a…

利用python工具you-get下载网页的视频文件

有时候我们可能在一个网站看到一个视频&#xff08;比如B站&#xff09;&#xff0c;想下载&#xff0c;但是页面没有下载视频的按钮。这时候&#xff0c;我们可以借助python工具you-get来实现下载功能。下面简要说下步骤 &#xff08;一&#xff09;因为使用的是python工具&a…

threejs渲染器和前端UI界面

1. three.js Canvas画布布局 学习本节课之前&#xff0c;可以先回顾下第一章节入门部分的6和12两小节关于threejs Canvas画布布局的讲解。 网页上局部特定尺寸&#xff1a;1.6 第一个3D案例—渲染器(opens new window) 全屏&#xff0c;随窗口变化:1.12 Canvas画布布局和全屏…

嵌入式编译工具链熟悉与游戏移植

在自己的虚拟机Ubuntu系统下&#xff0c;逐步编译 mininim源码(波斯王子重制开源版&#xff09; 指令流程 sudo apt-get remove liballegro5-dev liballegro-image5-dev \liballegro-audio5-dev liballegro-acodec5-dev liballegro-dialog5-dev sudo apt-get install automak…

IEEE P370:用于高达 50 GHz 互连的夹具设计和数据质量公制标准

大多数高频仪器&#xff0c;如矢量网络分析仪 &#xff08;VNA&#xff09; 和时域反射仪 &#xff08;TDR&#xff09;&#xff0c;都可以在同轴接口的末端进行非常好的测量。然而&#xff0c;复杂系统中使用的互连很少具有同轴接口。用于表征这些设备的夹具的设计和实施会对测…

随机响应噪声-极大似然估计

一、核心原因&#xff1a;噪声机制的数学可逆性 在随机响应机制&#xff08;Randomized Response&#xff09;中使用极大似然估计&#xff08;Maximum Likelihood Estimation, MLE&#xff09;是为了从扰动后的噪声数据中无偏地还原原始数据的统计特性。随机响应通过已知概率的…

二叉搜索树——红黑树

红黑树 概念红黑树的原理红黑树的效率红黑树的插入规则变色旋转变色红黑树的验证 代码如下 概念 红黑树本质也是一颗二叉搜索树&#xff0c;他的每个结点增加⼀个存储位来表⽰结点的颜⾊&#xff0c;可以是红⾊或者⿊⾊。通过对任何⼀条从根到叶⼦的路径上各个结点的颜⾊进⾏约…

PCB设计教程【强化篇】——USB拓展坞元件选型

前言 本教程基于B站Expert电子实验室的PCB设计教学的整理&#xff0c;为个人学习记录&#xff0c;旨在帮助PCB设计新手入门。所有内容仅作学习交流使用&#xff0c;无任何商业目的。若涉及侵权&#xff0c;请随时联系&#xff0c;将会立即处理 目录 前言 USB 拓展坞项目概述…

C++11新特性lambda的使用详解

得益于C11的发布&#xff0c;提供了提高效率的语法&#xff0c;C11以后是现代C&#xff0c;C98是传统C&#xff0c;这里来介绍lambda的使用和原理。 目录 1.lambda 2.列表捕捉 3&#xff0c;lambda的应用 4&#xff0c;lambda原理 1.lambda lambda表达式本质是一个匿名函…