Day7 C++ 指针

目录

什么是指针

指针变量的定义

指针变量定义语法

注意

指针所占内存空间

空指针

野指针

函数指针

声明函数指针

初始化函数指针

使用函数指针调用函数

指针的使用

const修饰指针

const修饰指针 --- 指针常量(constant pointer)

const修饰常量 --- 常量指针(pointer to const)

const即修饰指针,又修饰常量(constant pointer to const)

指针和数组

指针和函数

指针作为函数参数

返回指针的函数

函数指针

动态内存分配

什么是指针

C++中的指针是一种变量,它存储了一个内存地址。通过指针,我们可以访问和修改这个内存地址中的数据。

  • 内存编号是从0开始记录的,一般用十六进制数字表示

  • 可以利用指针变量保存地址,也可以通过指针间接访问内存

指针变量的定义

指针变量定义语法

数据类型 * 变量名;

int num = 10;  // 声明一个整数变量
int* ptr;  
ptr = &num ; // 将num的地址赋值给指针ptr
int num = 10;  // 声明一个整数变量
int* ptr = #  // 将num的地址赋值给指针ptr

注意

  • 普通变量存放的是数据,指针变量存放的是地址利用指针可以记录地址

  • 指针的声明需要指定所指向的数据类型,可以使用 "*"  符号进行声明。

  • " * "靠近数据类型或者靠近变量名都行,意义一样。   int*  a;   相当于  int  *a;

  • 我们可以通过 & 操作符(取地址符)获取变量的地址

  • 指针变量可以通过" * "操作符,操作指针变量指向的内存空间,这个过程称为解引用

  • 对指针变量解引用,可以操作指针指向的内存及所指内存的数据

指针所占内存空间

在32位系统中,指针通常占用4个字节(32位),而在64位系统中,指针通常占用8个字节(64位)。需要注意的是,由于不同系统和编译器的差异,指针的大小可能会有一些变化,但是通常情况下遵循上述的规律。指针的大小和指针所指向的类型无关。不论指针指向的是一个整数、字符、对象还是其他数据类型,指针本身的大小是相同的。

空指针

空指针(Null Pointer)是指向内存中编号为0的空间的指针。可以使用字面值常量nullptr或关键字NULL来表示空指针。常用于初始化指针变量

int* ptr = NULL;  // 使用NULL初始化指针// int* ptr = nullptr;  // 使用nullptr初始化指针

空指针可以作为合法的指针值存在,是一个特殊的指针值,表示指针不引用任何对象或函数。对空指针进行解引用或访问其指向的内容会导致未定义的行为。

野指针

野指针(Wild Pointer)是指向非法的内存空间的指针变量,指向的内存地址是未知、无效或未初始化的。野指针的出现通常是由于指针变量没有被正确初始化或者在释放了指针所指向的内存后仍然保留了指向已释放内存的指针。对野指针进行解引用或访问其指向的内容同样会导致未定义的行为。为了避免野指针的出现,我们应该始终确保指针在使用之前被正确初始化,且在不再需要时及时对指针进行释放或重置。

int * p = (int *)0x1100;//指针变量p指向内存地址编号为0x1100的空间       
cout << *p << endl;//访问野指针报错

函数指针

函数指针是指向函数的指针变量。它可以存储函数的地址,并且可以通过该指针来间接调用函数。函数指针允许我们以更灵活的方式使用函数,可以将函数作为参数传递给其他函数,或者将函数指针作为结构体的成员进行操作。

声明函数指针

使用 (*指针变量名) 来声明一个函数指针变量,括号中是指针变量的名称。

int (*funcPtr)(int, int); // 声明一个函数指针变量
初始化函数指针

将函数指针指向一个具体的函数,可以直接将函数的名称赋值给函数指针。

funcPtr = add; // 将函数指针指向 add 函数
使用函数指针调用函数

通过函数指针来间接调用相应的函数。

int result = funcPtr(5, 3); // 使用函数指针调用函数

指针的使用

const修饰指针

总结:指针常量,即指针是常量;常量指针,即常量的指针。

const修饰指针 --- 指针常量(constant pointer)

指针本身是一个常量,不能修改指针的值,但可以通过指针访问和修改指向的变量。

int x = 5;
int* const ptr = &x; // ptr 是一个指向整数的常量指针
*ptr = 10; // 可以通过 ptr 修改所指向的变量的值,即 x 的值被修改为 10
// ptr = nullptr; // 错误,不能修改指针的值
const修饰常量 --- 常量指针(pointer to const)

指针指向的对象是一个常量,不能通过指针修改对象的值。

int x = 5;
const int* ptr = &x; // ptr 是一个指向常量整数的指针
// *ptr = 10; // 错误,不能通过 ptr 修改所指向的常量的值
x = 10; // 可以直接修改变量的值
ptr = nullptr; // 可以修改指针的值
const即修饰指针,又修饰常量(constant pointer to const)

既不能修改指针的值,也不能通过指针修改所指向的常量的值。

const int* const ptr = &x; // ptr 是一个指向常量整数的常量指针
// *ptr = 10; // 错误,不能通过 ptr 修改所指向的常量的值
// ptr = nullptr; // 错误,不能修改指针的值

指针和数组

数组名本身就是一个指向数组首元素的指针,可以通过指针遍历数组元素。

例如 int arr[] = {1, 2, 3}; int* ptr = arr;

将数组名 arr 的地址赋给指针 ptr,然后可以通过操作指针来访问数组元素。

例如 *ptr 是第一个元素,*(ptr + 1) 是第二个元素

(可以把指针当数组用,也能把数组当指针用)

指针和函数

利用指针作函数参数,可以修改实参的值,如果不想修改实参,就用值传递,如果想修改实参,就用地址传递

指针作为函数参数

可以将指针作为函数的参数,通过指针传递数据或者修改指针指向的数据。这样可以避免在函数中进行大量的数据复制,提高程序的效率。

void updateValue(int* ptr) {*ptr = 10; // 修改指针指向的数据
}
int main() {int x = 5;updateValue(&x); // 将 x 的地址传递给函数// 现在 x 的值变为 10return 0;
}
返回指针的函数

函数可以返回指针类型的值,这样可以返回动态分配的内存地址或者现有变量的地址等。但需要注意在返回指针之前,确保指针指向的数据仍然有效。

int* createArray() {int* arr = new int[5]; // 动态分配一个 int 数组for (int i = 0; i < 5; ++i) {arr[i] = i+1;}return arr; // 返回数组的首地址
}
int main() {int* ptr = createArray(); // 接收返回的指针// 使用指针访问数组的元素for (int i = 0; i < 5; ++i) {cout << ptr[i] << " "; // 输出: 1 2 3 4 5}delete[] ptr; // 释放动态分配的内存return 0;
}
函数指针

见上文

动态内存分配

使用 new 关键字可以在堆上动态分配内存,并返回一个指向分配内存的指针。

int* ptr = new int;//动态分配了一个整数大小的内存,并将其地址赋给指针 ptr。delete ptr;//使用完毕后,需要使用 delete 关键字释放动态分配的内存

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

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

相关文章

libuv库学习笔记-advanced-event-loops

Advanced event loops libuv提供了非常多的控制event-loop的方法&#xff0c;你能通过使用多loop来实现很多有趣的功能。你还可以将libuv的event loop嵌入到其它基于event-loop的库中。比如&#xff0c;想象着一个基于Qt的UI&#xff0c;然后Qt的event-loop是由libuv驱动的&am…

会议OA项目之会议发布(一)

目录 前言&#xff1a; 会议发布的产品原型图&#xff1a; 1.会议发布 1.1实现的特色功能&#xff1a; 1.2思路&#xff1a; 使用的数据库&#xff1a; 我们要实现多功能下拉框的形式选择可以参考原文档&#xff1a;https://hnzzmsf.github.io/example/example_v4.html#down…

Michael.W基于Foundry精读Openzeppelin第14期——SafeMath.sol

Michael.W基于Foundry精读Openzeppelin第14期——SafeMath.sol 0. 版本0.1 SafeMath.sol 1. 目标合约2. 代码精读2.1 tryAdd(uint256 a, uint256 b) && trySub(uint256 a, uint256 b) && tryMul(uint256 a, uint256 b) && tryDiv(uint256 a, uint256 b…

php的设计模式有哪些

1&#xff0c;创建设计模式&#xff08;Creational Patterns&#xff09;(5种)&#xff1a; 用于创建对象时的设计模式。更具体一点&#xff0c;初始化对象流程的设计模式。当程序日益复杂时&#xff0c;需要更加灵活地创建对象&#xff0c;同时减少创建时的依赖。而创建设计模…

LlaMA2微调实战

LLaMA2-SFT LLaMA2-SFT, Llama-2-7B微调(transformers)/LORA(peft)/推理 Gtihub地址 https://github.com/yongzhuo/Llama2-SFT prompt text_1 f"".join(["[INST] <<SYS>>\n ""You are a helpful, respectful and honest assista…

数组专题攻破新学习笔记

数组专题攻破新学习笔记 1.移除有序数组中的重复项和移除元素2.二分查找需注意3.在排序数组中查找元素的第一个和最后一个位置4.最长回文串5.区域和检索-数组不可变 1.移除有序数组中的重复项和移除元素 思想一样但是细节不一样 思想一样就是 设置快慢指针&#xff0c;快指针…

ubuntu远程控制小车 运行rviz时报错

我买的是wheeltec的小车&#xff0c;测试rgbd相机时想在ubuntu上的rviz中显示小车的姿态和看到的rgb和depth图&#xff0c;但是ubuntu中rostopic list和rviz都找不到小车发布的话题信息&#xff0c;运行rqt_image_view时可以显示图片信息。 最终wheeltec的技术人员lucas帮我找了…

nodejs+vue+elementui汽车销售网站

前端技术&#xff1a;nodejsvueelementui,视图层其实质就是vue页面&#xff0c;通过编写vue页面从而展示在浏览器中&#xff0c;编写完成的vue页面要能够和控制器类进行交互&#xff0c;从而使得用户在点击网页进行操作时能够正常。 可以设置中间件来响应 HTTP 请求。 Express …

游戏小记-全屏与无边框

“LoL” 是指英雄联盟&#xff08;League of Legends&#xff09;&#xff0c;一款非常流行的多人在线战术游戏。在游戏设置中&#xff0c;“全屏” 和 “无边框” 是两种不同的窗口模式&#xff0c;它们有以下区别&#xff1a; 全屏模式&#xff1a; 在全屏模式下&#xff0c;…

Kafka 入门到起飞 - Kafka怎么做到保障消息不会重复消费的? 消费者组是什么?

Kafka怎么做到避免消息重复消费的&#xff1f; 消费者组是什么&#xff1f; 消费者&#xff1a; 1、订阅Topic&#xff08;主题&#xff09; 2、从订阅的Topic消费&#xff08;pull&#xff09;消息&#xff0c; 3、将消费消息的offset&#xff08;偏移量&#xff09;保存在K…

西安电子科技大学

前言 本篇文章投稿与以下活动 【西安城市开发者社区】探索西安高校&#xff1a;展现历史与创新的魅力 资料参考与百度百科 学校简介 西安电子科技大学&#xff08;Xidian University&#xff09;&#xff0c;简称“西电”&#xff0c;位于陕西省西安市&#xff0c;是中央部…

浅析C++临时变量

在C/C中&#xff0c;临时变量&#xff08;也称为临时对象&#xff09;具有常量性质&#xff0c;是由编译器自动创建的&#xff0c;并在表达式求值期间临时存在。它们主要用于存储中间结果&#xff0c;使表达式的求值过程更加高效和简洁。临时变量的生命周期仅限于表达式的求值过…

14.Netty源码之模拟简单的HTTP服务器

highlight: arduino-light 简单的 HTTP 服务器 HTTP 服务器是我们平时最常用的工具之一。同传统 Web 容器 Tomcat、Jetty 一样&#xff0c;Netty 也可以方便地开发一个 HTTP 服务器。我从一个简单的 HTTP 服务器开始&#xff0c;通过程序示例为你展现 Netty 程序如何配置启动&a…

2023年全国程序员薪酬排行天梯榜

文章目录 ⭐️ 2023年全国程序员薪酬排行天梯榜 在过去很长的一段时间内&#xff0c;网上总有一个声音&#xff1a;“大厂裁员”、“程序员内卷严重”、“程序员人员过盛”、“35岁中年危机”、“码农吃的青春饭”、“互联网寒冬” 等等等等。 讲道理&#xff0c;我对这种人为的…

【通过改变压缩视频的分辨率实现高效的视频语义分割】CVPR2022论文精度

Efficient Semantic Segmentation by Altering Resolutions for Compressed Videos Efficient Semantic Segmentation by Altering Resolutions for Compressed VideosBasic Information:论文简要 :背景信息:a. 理论背景:b. 技术路线: 结果:a. 详细的实验设置:b. 详细的实验结果…

云原生周刊:K8s v1.28 中的结构化身份验证配置

开源项目推荐 KubeLinter KubeLinter 是一种静态分析工具&#xff0c;用于检查 Kubernetes YAML 文件和 Helm 图表&#xff0c;以确保其中表示的应用程序遵循最佳实践。 DB Operator DB Operator 减轻了为 Kubernetes 中运行的应用程序管理 PostgreSQL 和 MySQL 实例的痛苦…

7.1 String StringBuffer 和 StringBuilder 的区别是什么? String 为什么是不可变的?

可变性 简单的来说&#xff1a;String 类中使用 final 关键字修饰字符数组来保存字符串&#xff0c;private final char value[]&#xff0c;所以String 对象是不可变的。 补充&#xff08;来自issue 675&#xff09;&#xff1a;在 Java 9 之后&#xff0c;String 、StringBu…

LLM Data Pipelines: 解析大语言模型训练数据集处理的复杂流程

编者按&#xff1a;在训练大语言模型的过程中,构建高质量的训练数据集是非常关键的一步&#xff0c;但关于构建大模型训练所需数据集的通用数据处理流程&#xff08;Data pipelines)的相关资料极为稀少。 本文主要介绍了基于Common Crawl数据集的数据处理流程。首先,文章概述了…

复现YOLOv8改进最新MPDIoU:有效和准确的边界盒回归的损失,打败G/E/CIoU,效果明显!!!

MPDIoU: A Loss for Efficient and Accurate Bounding Box Regression 论文简介MPDIoU核心设计思路论文方法实验部分加入YOLOv5代码论文地址:https://arxiv.org/pdf/2307.07662.pdf 论文简介 边界盒回归(Bounding box regression, BBR)广泛应用于目标检测和实例分割,是目标…

【业务功能篇56】SpringBoot 日志SLF4J Logback

3.5.1 日志框架分类与选择 3.5.1.1 日志框架的分类 日志门面 (日志抽象)日志实现JCL(Jakarta Commons Logging) SLF4J(Simple Logging Facade for Java)Jul(Java Util Logging) , Log4j , Log4j2 , Logback 记录型日志框架 Jul (Java Util Logging)&#xff1a;JDK中的日志…