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

C++-------指针

把地址当做数值

在 C++ 中,指针本质上就是存储内存地址的变量。每个变量在内存中都有一个唯一的地址,通过取地址运算符 & 可以获取变量的地址,这个地址本质上是一个整数(在 32 位系统中是 32 位整数,64 位系统中是 64 位整数)。例如:

int num = 10;
int* ptr = #  // ptr 存储了 num 的内存地址

这里,&num 获取 num 的地址并赋值给指针 ptr,我们就可以把这个地址当成一个数值来操作,不过通常不会像普通整数那样随意运算,更多是为了实现指针相关的语义,比如指针偏移。

声明指针变量

指针变量的声明需要指定它指向的数据类型,语法形式为 数据类型* 指针变量名。例如:

int* p1;  // 指向 int 类型数据的指针
double* p2;  // 指向 double 类型数据的指针
char* p3;  // 指向 char 类型数据的指针

声明后指针变量需要初始化,指向合法的内存地址,否则可能出现悬空指针(野指针)的情况,引发未定义行为。初始化方式可以是指向已声明变量的地址,或者动态分配内存:

int num = 5;
int* p = #int* q = new int;  // 动态分配一个 int 大小的内存,q 指向这块内存
*q = 10;
delete q;  // 使用完后释放内存

基本的指针运算

  • 指针偏移:指针加上或减去一个整数 n,实际偏移的字节数是 n 乘以指针所指向数据类型的大小。例如:
int arr[5] = {1, 2, 3, 4, 5};
int* p = arr;  // p 指向数组首元素
p++;  // p 指向数组第二个元素,偏移了 sizeof(int) 个字节
  • 指针相减:两个指向同一数组元素的指针相减,结果是它们之间间隔的元素个数,而不是字节数。
int* p1 = &arr[1];
int* p2 = &arr[3];
int diff = p2 - p1;  // diff 为 2

指向结构和对象的指针

对于结构体和类对象,同样可以用指针来指向它们:

struct Point {int x;int y;
};Point p = {1, 2};
Point* ptr = &p;  // 指向结构体对象的指针// 通过指针访问结构体成员
ptr->x = 3;
ptr->y = 4; 

对于类也是类似:

class MyClass {
public:void print() {cout << "Hello" << endl;}
};MyClass obj;
MyClass* pObj = &obj;
pObj->print();

关键字 this

this 是 C++ 类中的一个关键字,它是一个指向当前对象的指针。当类的成员函数被调用时,this 指针会自动传递给函数,指向调用该函数的对象实例。例如:

class Rectangle {
public:int width, height;Rectangle(int w, int h) {this->width = w;this->height = h;}
};

这里 this 用来区分形参 wh 和类成员变量 widthheight,明确表示是给类成员变量赋值。

特殊指针 NULL

NULL 是一个预定义的宏,在 C++ 中它表示空指针,即不指向任何有效内存地址的指针。通常用于指针初始化,或者判断指针是否有效:

int* p = NULL;
if (p == NULL) {// 指针未指向有效地址
}

在现代 C++ 中,更推荐使用 nullptr,它是类型安全的空指针常量,避免了一些因 NULL 类型不明确带来的潜在错误 。

指针和引用调用

  • 指针调用:通过指针访问对象或变量,可以修改所指向内存的内容。例如:
void increment(int* num) {(*num)++;
}int main() {int n = 5;increment(&n);cout << n << endl;  // 输出 6return 0;
}
  • 引用调用:引用是对象的别名,声明形式为 数据类型& 引用名 = 对象名 。引用必须初始化,之后对引用的操作等同于对它绑定对象的操作:
void increment(int& num) {num++;
}int main() {int n = 5;increment(n);cout << n << endl;  // 输出 6
}

引用相较于指针,语法上更加简洁直观,且不需要像指针那样担心空指针的问题,但引用一旦绑定就不能再重新绑定到其他对象。
在这里插入图片描述

C++中this关键字的作用是什么?

在C++中,this关键字主要有以下几个重要作用:

  1. 区分成员变量和局部变量(或参数)
    • 在类的成员函数中,如果局部变量(包括函数参数)与成员变量同名,使用this指针可以明确地访问成员变量。例如:
class MyClass {
private:int value;
public:MyClass(int value) {// 使用this指针来区分参数value和成员变量valuethis->value = value;}void printValue() {std::cout << this->value << std::endl;}
};
- 这里,`this->value` 表示类的成员变量`value`,而单独的`value`在构造函数的参数列表中是指传入的参数。通过`this`指针,可以确保将参数正确地赋值给成员变量,并在其他成员函数中正确地访问成员变量。
  1. 在对象链式调用中返回对象本身
    • this指针可以用于返回对象本身,使得对象的方法调用可以像链条一样连续进行。例如,考虑一个表示数学向量的类,我们可以定义加法操作,使得多个向量相加的操作可以链式调用:
class Vector {
private:double x;double y;
public:Vector(double x, double y) : x(x), y(y) {}Vector& add(const Vector& other) {this->x += other.x;this->y += other.y;// 返回对象本身,以便进行链式调用return *this;}void print() {std::cout << "(" << x << ", " << y << ")" << std::endl;}
};
- 可以这样使用:
int main() {Vector v1(1.0, 2.0);Vector v2(3.0, 4.0);Vector v3(5.0, 6.0);v1.add(v2).add(v3).print();return 0;
}
- 在`add`函数中,`return *this`返回了当前对象的引用,这样就可以继续调用该对象的其他成员函数,实现链式操作,使得代码更加简洁和易读。
  1. 作为函数参数传递当前对象的地址
    • 在某些情况下,可能需要将当前对象的地址传递给其他函数。this指针本质上是指向当前对象的指针,所以可以直接将this作为参数传递。例如,当需要将对象插入到一个数据结构(如链表)中时,可能需要传递对象的指针:
class Node {
private:int data;Node* next;
public:Node(int data) : data(data), next(NULL) {}void insertIntoList(Node*& head) {// 一些插入节点到链表的逻辑,可能需要传递当前对象的指针if (head == NULL) {head = this;} else {// 其他插入逻辑}}
};
- 这里`this`作为当前对象(`Node`)的指针被用于在链表中插入节点的操作,帮助实现对象与其他数据结构之间的交互。

总之,this关键字在C++中是一个非常重要的工具,用于在类的内部明确地引用当前对象,提供了对成员变量和成员函数的正确访问方式,同时也支持了一些高级的编程技巧,如链式调用等。

在这里插入图片描述

相关文章:

C++-------指针

把地址当做数值 在 C 中&#xff0c;指针本质上就是存储内存地址的变量。每个变量在内存中都有一个唯一的地址&#xff0c;通过取地址运算符 & 可以获取变量的地址&#xff0c;这个地址本质上是一个整数&#xff08;在 32 位系统中是 32 位整数&#xff0c;64 位系统中是 …...

Linux文件目录 --- 移动和改名命令MV、强制移动、试探性移动过、按时间移动

二、MV移动改名命令 重命名文件&#xff1a;mv [选项] 旧文件名 新文件名 移动文件/文件夹&#xff1a;mv [选项] 源文件 目标目录 选项作用-b当覆盖文件时会对被覆盖文件进行先行备份。-i交互式操作&#xff0c;当目标文件已经存在时&#xff0c;会询问是否覆盖。-n试探性覆盖…...

03.HTTPS的实现原理-HTTPS的工作流程

03.HTTPS的实现原理-HTTPS的工作流程 简介1. HTTPS的工作流程1.1. TCP的工作流程1.1.1. 三次握手的详细步骤1.1.2. 三次握手的作用 1.2. HTTPS的工作流程1.2.1. HTTPS与TCP的关系1.2.2. HTTPS的工作流程 2. 公钥和私钥的作用3. 对称密钥的生成和交换4. 对称加密和非对称加密的区…...

vue实现批量下载文件流并压缩

为了实现文件流压缩&#xff0c;我们可以使用 JSZip 和 FileSaver 这两个第三方库。JSZip 是一个用于创建、读取和编辑 .zip 文件的 JavaScript 库&#xff0c;而 FileSaver 则用于在客户端保存文件。 ‌JSZip‌&#xff1a;用于创建和操作zip文件。可以通过 file 方法将文件添…...

前端入门之VUE--ajax、vuex、router,最后的前端总结

前言 VUE是前端用的最多的框架&#xff1b;这篇文章是本人大一上学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。本人不是学前端的&#xff0c;这个是大一的时候上学的和做的笔记&#xff0c;那个时候学的也蒙&#xff0c;故这里对前端做一个总…...

安装k8s涉及命令(方便放到txt离线使用)

查看操作系统信息 uname -a # 查看所有操作系统信息 uname -s # 查看内核名称 uname -r # 查看内核版本号 uname -m # 查看机器硬件名称 cat /etc/os-release # 查看所有操作系统信息 配置hosts cat >> /etc/hosts << EOF 172.171.16.147 crawler-k8s-mast…...

FLV视频封装格式详解

目录(?)[-] OverviewFile Structure The FLV headerThe FLV File BodyFLV Tag Definition FLVTAGAudio TagsVideo TagsSCRIPTDATA onMetaDatakeyframes Overview Flash Video(简称FLV),是一种流行的网络格式。目前国内外大部分视频分享网站都是采用的这种格式. File Structure…...

搭建vue3+vant项目架构

git代码仓库&#xff0c;直接下载压缩包使用 1、首先要安装node.js(18.3 或更高版本) 2、创建vue3项目 npm create vuelatest然后按照自己的需要进行选择就行 到此vue3项目创建完成&#xff0c;接下来是搭建项目架构 3、配置Vant (移动端ui) vue3项目引入vant&#xff0c…...

【Linux】进程间通信 -> 匿名管道命名管道

进程间通信的目的 数据传输&#xff1a;一个进程许需要将它的数据发送给另外一个进程。资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它们发生了某种事件&#xff08;如进程终止时要通知父进程…...

大数据开发学习路线

编程语言&#xff1a; Python&#xff1a;数据分析、数据预处理 Java&#xff1a;Hadoop和许多大数据工具的基础 Scala&#xff1a;用于Apache Spark数据库知识&#xff1a; SQL和NoSQL数据库的基本概念 数据库系统如MySQL、MongoDB等操作系统&#xff1a; Linux基础命令和脚本…...

华为云计算HCIE笔记05

第七章&#xff1a;其它模式 灾备组网 高可用性组网&#xff0c;单核心场景下&#xff0c;直接在两个站点中设置一个第三方仲裁站点&#xff0c;两个站点同时连接到仲裁&#xff0c;并且连接到对方。一旦出现问题&#xff0c;则由仲裁站点进行判断&#xff0c;进行业务切换 双核…...

wordpress网站用token登入开发过程

生成跳转token 示例&#xff1a; function generate_login_token($user_id, $secret_key) {$payload [user_id > $user_id,timestamp > time(),];$payload_json json_encode($payload);$signature hash_hmac(sha256, $payload_json, $secret_key);return base64_en…...

Python基础知识回顾

数据类型 Python可以区分整数&#xff08;integers、下文简写为int&#xff09;、浮点数&#xff08;float&#xff09;、字符串&#xff08;string&#xff09;和布尔值&#xff08;Boolean&#xff09;等数据类型。 1&#xff09;int是可正可负的整数 2&#xff09;float包…...

C++--------效率和表示

C 效率和表示 效率 时间效率&#xff1a;在 C 中&#xff0c;不同的数据结构和算法有着各异的时间复杂度。例如&#xff0c;访问数组元素的时间复杂度是 O ( 1 ) O(1) O(1)&#xff0c;而遍历链表查找元素的时间复杂度最坏情况下是 O ( n ) O(n) O(n)。选择合适的算法与数据…...

在 Ubuntu 服务器上添加和删除用户

在 Ubuntu 服务器上添加和删除用户通常使用命令行工具&#xff0c;如 adduser、useradd、deluser 等。以下是详细的步骤和说明&#xff1a; 添加用户 使用 adduser 命令 adduser 是一个更为友好的脚本&#xff0c;用于创建新用户并设置相关信息。 添加新用户 sudo adduser 用…...

安卓 SystemServer 启动流程

目录 引言 Android系统服务启动顺序 zygote fork SystemServer 进程 SystemServer启动流程 1、SystemServer.main() 2、SystemServer.run() 3、初始化系统上下文 4、创建系统服务管理 5、启动系统各种服务 总结 引言 开机启动时 PowerManagerService 调用 AudioSer…...

深度分析 es multi_match 中most_fields、best_fields、cross_fields区别

文章目录 1. multi_match 查询的类型1.1 best_fields&#xff08;默认&#xff09;1.2 most_fields1.3 cross_fields 2. 不同类型的示例查询示例数据&#xff1a; 3. 示例 1: 使用 best_fields查询&#xff1a;说明&#xff1a; 4. 示例 2: 使用 most_fields查询&#xff1a;说…...

中职计算机网络技术理实一体化实训室建设方案

构建理实一体化教学模式对于改善中等职业学校计算机网络技术课程的教学现状、提升教学质量和效率具有重要意义。在中职教育不断深化改革的背景下&#xff0c;积极推进理实一体化教学模式的发展&#xff0c;不仅能够提高计算机网络技术课程的教学水平&#xff0c;满足教育改革的…...

Java技术专家视角解读:SQL优化与批处理在大数据处理中的应用及原理

引言 在大厂架构中&#xff0c;提升系统性能和稳定性是技术团队的首要任务。SQL优化与批处理作为两大关键技术手段&#xff0c;对于处理大规模数据和高并发请求具有重要意义。本文将从Java技术专家的视角出发&#xff0c;深入探讨SQL优化与批处理在大数据处理中的应用及原理&a…...

数据结构(Java版)第六期:LinkedList与链表(一)

目录 一、链表 1.1. 链表的概念及结构 1.2. 链表的实现 专栏&#xff1a;数据结构(Java版) 个人主页&#xff1a;手握风云 一、链表 1.1. 链表的概念及结构 链表是⼀种物理存储结构上⾮连续存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的引⽤链接次序实现的。与火车…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...