43. C++ 指针合集

C/C++指针合集
1. 指针变量的空间大小

指针变量的空间大小是固定值(64位下为8字节, 32位下为4字节),跟其指向的数据类型及多级指针无关,与编译平台相关(指针大小由当前CPU运行模式的寻址位数决定)。

2. 指针的宽度(步长)

指针宽度与指针变量的数据类型相关,其宽度就是对应的数据类型占用的字节数。

3. 野指针
  • 指针定义之后未初始化,出现了随机值。

  • 数组下标越界或者是访问了不存在的元素。

  • 使用了已经销毁的内存地址。

注意

  • 指针变量定义完成之后要初始化;

  • 小心指针越界;

  • 指针变量使用之前要检查是否有效;

  • 指针使用完成之后赋值为nullptr;

4. void指针

解引用时要强制转换

void *p1 = &a;
cout<<*(int *)p1<<endl;
5. const 指针

*const int p = &a; const修饰的是int,解引用正常,但是不能修改其指向空间里面的具体内容;

int * const p = &a; const修饰的是变量p,不可修改其指向,但可修改其指向空间里面的具体内容;

const int * const &p = &a; 两个const修饰,指针指向的内容和指针指向均不可修改;

6. 多级指针

*int p1 = &a; p1表示指针变量,int表示指向的数据类型;

int **p2 = &p1 p2表示指针变量,int *表示指向的数据类型;

int ***p3 = &p2 p3表示指针变量,int **表示指向的数据类型;

7. 用指针操作数组
int a[3] = {1, 2, 3};
cout<<a<<endl; //等价于&a[0]
cout<<&a<<endl; //整个数组的指针
cout<<&a[0]<<endl; //数组中首个元素的指针cout<<a<<a+1<<a+2<<endl; //步长4字节, 1个int
cout<<&a<<&a+1<<&a+2<<endl; //&a的步长单位是整个数组的空间大小
cout<<&a[0]<<&a[0]+1<<&a[0]+2<<endl; //1个intsizeof(a) = 12字节
sizeof(&a) = sizeof(&a[0]) = 8
8. 用指针操作多维数组
int a[2][3] = {11, 22, 33, 44, 55, 66};
cout<<a<<endl; //等价于&a[0]
cout<<&a<<endl; //整个数组的指针
cout<<a[0]<<endl; //等价于&a[0][0]
cout<<&a[0]<<endl; //数组中首个元素a[0][0]的指针
cout<<&a[0][0]<<endl; //数组中首个元素的指针cout<<sizeof(a)<<endl; //24
cout<<sizeof(a[0])<<endl; //12
cout<<sizeof(a[0][0])<<endl; //4cout<<a<<a+1<<a+2<<endl; //步长12个字节
cout<<&a<<&a+1<<&a+2<<endl; //步长24个字节
cout<<&a[0]<<&a[0]+1<<&a[0]+2<<endl; //步长12字节
cout<<&a[0][0]<<endl; //步长4字节
9. 指针的运算
指针与整数运算
int a[4] = {1, 2, 3, 4};
cout<<a<<*a<<endl;
cout<<a+1<<*(a+1)<<endl; // 步长4
cout<<a+2<<*(a+2)<<endl;
cout<<a+10<<*(a+10)<<endl; //越界int *p = &a[3];
cout<<p<<*(p-2)<<endl;
cout<<p-10<<*(p-10)<<endl; //越界
自增++/自减–
int *p = a;
cout<<p<<*p<<endl;
p++;
cout<<p<<*p<<endl;

指针与整数的加减运算,每次加减的步长是与其对应的数据类型的长度。

指针与指针的运算

==

< >

10. 指针数组
11. 函数指针
void fun1() {cout<<"fun1"<<endl;
}int fun2(int a, int b) {return a + b;
}int main() {void (*pfun1) = &fun1; //获取函数指针(*pfun1)(); //用函数指针调用函数,解引用int (*pfun2)(int, int) = &fun2; //获取函数指针int c = (*pfun2)(1, 2);cout<<(&fun2 == fun2)<<endl;&fun2(); //fun2:定位到某一地址 ():执行其对应的代码块// 函数名就是一个隐式的指针,函数名在程序里面,就是指针地址的别名。// 通过函数指针调用函数是没有办法内联的,存在函数调用开销
}
12. 结构体内存对齐
struct T1 {int a;int *p;char c;
};
struct T1 t;
cout<<sizeof(t)<<endl;
//结构体变量的 起始地址 要能被其最大的成员整除
//结构体变量的 总体大小 要能被其最大的成员整除
//结构体变量的 每个成员 相对于开始地址的偏移量,要被其自身大小整除
13. calloc、realloc

calloc 分配完空间后会清0,相当于malloc + memset

realloc 是表示将原有的指针变量的空间进行扩充,如果原指针指向的空间后面还有足够大的空间,就直接在原地址扩充;

如果原地址没有足够大的空间,则会开辟新地址,并将原来的数据拷贝到新空间。

14. 智能指针
shared_ptr 定义和初始化
int main() {shared_ptr<int> p1; //shared_ptr定义完成之后就是空指针int *p2 = new int; //野指针cout<<p1 == nullptr<<p1 == NULL<<endl;cout<<p2 == nullptr<<p2 == NULL<<endl;shared_ptr<int> p3(new int(123)); // 初始化shared_ptr<int> p4 = new int(123); //不支持隐式类型转换
}
//智能指针做函数返回值
shared_ptr<int>func1(int a) {return shared_ptr<int>(new int(a));
}
int main() {shared_ptr<int>p1 = func(123);shared_ptr<int>p2 = p1;shared_ptr<int>p3(p2);
}
int main() {int *p1 = new int(123); //用new定义的指针为裸指针,不建议用裸指针来初始化智能指针。shared_ptr<int>p2(p1);shared_ptr<int>p3 = p2;
}
int main() {shared_ptr<int>p1 = make_shared<int>(123); //初始化shared_ptr<int>p2 = p1;shared_ptr<int>p3(p2);
}
shared_ptr 共享原理和引用计数

所谓共享,是指也可能有其他指针指向该块内存,同时也有读写和销毁的权限;

int main() {shared_ptr<int>p1 = make_shared<int>(1234);shared_ptr<int>p2 = p1;shared_ptr<int>p3(p2);//实现共享的原理。每个shared_ptr都会维护一个其自身指向那个内存空间的引用计数器,并随时同步更新,以达到与其他shared_ptr同步的目的//维护计数器需要额外的开销
}

引用计数器的增加和删除

  1. 新建一个shared_ptr,并初始化其指向,此时,该变量的引用计数器为1;
  2. 用上面的shared_ptr变量初始化一个新的shared_ptr,此时,指向同一个内存地址的shared_ptr引用计数器都要+1;
  3. 如果将shared_ptr作为一个实参传递到一个函数里面,在函数声明周期内,函数也有操作该内存的权限,引用计数器也要+1;
  4. 如果函数将一个shared_ptr作为返回值返回,并且有变量接受,则指向对应内存地址的shared_ptr引用计数器也要+1;

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

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

相关文章

杨中科 ASP.NET DI综合案例

综合案例1 需求说明 1、目的:演示DI的能力; 2、有配置服务、日志服务&#xff0c;然后再开发一个邮件发送器服务。可以通过配置服务来从文件、环境变量、数据库等地方读取配置&#xff0c;可以通过日志服务来将程序运行过程中的日志信息写入文件、控制台、数据库等。 3、说明…

第三百四十九回

文章目录 1. 概念介绍2. 原理与方法2.1 知识对比2.2 使用方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"加密包crypto"相关的内容&#xff0c;本章回中将介绍characters包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 在项目中会遇到获取字…

String类常用方法(Java)

String类 字符串相减/替换 使用 String 类的 replace() 方法来实现这个功能: replace(“target”,“replacement”) 如果你想将引号添加到字符串中&#xff0c;你可以使用转义字符 \" 来表示双引号。 String str1 "abcdefg"; String str2 "bcd"…

Django实战:部署项目 【资产管理系统】,Django完整项目学习研究(项目全解析,部署教程,非常详细)

导言 关于Django&#xff0c;我已经和大家分享了一些知识&#xff0c;考虑到一些伙伴需要在实际的项目中去理解。所以我上传了一套Django的项目学习源码&#xff0c;已经和本文章进行了绑定。大家可以自行下载学习&#xff0c;考虑到一些伙伴是初学者&#xff0c;几年前&#…

OpenAI又出王炸,Sora是否要开启视频AI新时代?

OpenAI又出王炸&#xff0c;Sora是否要开启视频AI新时代&#xff1f; 关注微信公众号 DeepGoAI 前几天我们还在讨论 如何让ChatGPT3.5变得更聪明 今天OpenAI就带着新王炸出现了 如同ChatGPT一般 在计算机领域掀起轩然大波 开启真正视频AI新时代 那就是 Sora 很多同学可…

结构体对齐规则及为什么会有结构体对齐

前言&#xff1a; 大家在学习结构体中&#xff0c;在计算结构体大小时想必会很疑惑&#xff0c;为什么结构体的大小不是按照常理像数组一样一个字节一个字节的挨在一起放&#xff1f;今天带大家一起深入探讨一下背后的规则和原因。 结构体对齐规则&#xff1a; 结构体对齐其实…

离散数学截图2

为什么G中阶大于2的元素&#xff0c;一定有偶数个 在有限群G中&#xff0c;阶大于2的元素个数一定是偶数的原因如下&#xff1a; 设 aaa 是群G中一个阶大于2的元素&#xff0c;那么根据群的定义和阶的概念&#xff08;即某个元素的幂次使得其等于单位元的最小正整数&#xff…

【Linux】 Linux 小项目—— 进度条

进度条 基础知识1 \r && \n2 行缓冲区3 函数介绍 进度条实现版本 1代码实现运行效果 版本2 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下一篇文章见&#xff01;&#xff01;&#xff01; 基础知识 1 \r &&a…

linux 安装docker

目录 环境 操作步骤 1 下载脚本 2 执行脚本 3 检查docker版本&#xff0c;证明安装成功 环境 阿里云 ubuntu 22.04 64位 操作步骤 参考linux系统安装docker-腾讯云开发者社区-腾讯云 (tencent.com) 1 下载脚本 curl -fsSL https://get.docker.com -o get-docker.sh …

牛客小白月赛87

说明 年后第一次写题&#xff0c;已经麻了&#xff0c;这次的题很简单但居然只写了两道题。有种本该发挥80分的水平&#xff0c;但是只做出了20分的水平的感觉。不过剩下几个题&#xff08;除了G题&#xff09;&#xff0c;比完赛一小时内就AC了。欢迎大家交流学习。&#xff0…

SpringBoot 整合 Redis 全面教程:从配置到使用

Redis 是一种高性能的键值存储数据库&#xff0c;而 Spring Boot 是一个简化了开发过程的 Java 框架。将两者结合&#xff0c;可以轻松地在 Spring Boot 项目中使用 Redis 来实现数据缓存、会话管理和分布式锁等功能。 一、添加 Redis 依赖 在 pom.xml 文件中添加 Redis 相关…

OpenCV 笔记(22):图像的缩放——最近邻插值、双线性插值算法

1. 图像缩放 1.1 简介 图像缩放是指通过增加或减少像素来改变图像尺寸的过程&#xff0c;是图像处理中常见的操作。图像缩放会涉及效率和图像质量之间的权衡。 图像放大&#xff08;也称为上采样或插值&#xff09;的主要目的是放大原图像&#xff0c;以便在更高分辨率的显示设…

学习 JavaScript 闭包

1. 前言 闭包是 JavaScript 中一种非常重要的概念&#xff0c;它允许函数访问其外部作用域中的变量&#xff0c;即使在函数被返回或者在其原始定义的作用域之外执行时仍然可以访问这些变量。 在讲解闭包之前我们得弄清楚下面的概念&#xff1a; 作用域链&#xff1a; JavaSc…

RK3568笔记十五:触摸屏测试

若该文为原创文章&#xff0c;转载请注明原文出处。 使用正点原子的ATK-RK3568板子&#xff0c;一直在测试屏幕和视频&#xff0c;突然想到触摸屏测试&#xff0c;一直没有用过&#xff0c;原子给的demo跑的是QT系统&#xff0c;触摸功能是正常的&#xff0c;测试一下&#xf…

Java Arrays源码剖析

Java中有一个类Arrays,包含一些对数组操作的静态方法&#xff0c;本文主要就来讨论这些方法以避免重新造轮子&#xff0c;在需要的时候自己实现它不具备的功能。 toString Arrays的toString()方法可以方便地输出一个数组的字符串形式&#xff0c;以便查看。它有9个重载的方法…

MySQL的JDBC操作、pymysql操作

JDBC JDBC (Java DataBase Connectivityjava数 据库连接)是一种用于执行SQL语句的Java API。 JDBC是Java访问数据库的标准规范&#xff0c;可以为不同的关系型数据库提供统一访问&#xff0c; 它由一组用Java语言编写的接口和类组成。 JDBC需要连接驱动&#xff0c;驱动是两个设…

学习天机02

1.注入bean的写法 构造函数的注入 2.回答和评论 在做这个功能的时候需要理解一些概念&#xff0c;张三提出问题就是提问者&#xff0c;李四去回答张三的问题&#xff0c;李四就是回答者&#xff0c;王五去回答李四的评论&#xff0c;王五就是评论者。 在提供的InteractionRep…

reprod_log复现精度对比小工具

reprod_log复现精度对比小工具 主要用于对比和记录模型复现过程中的各个步骤精度对齐情况 pip 安装 pip3 install reprod_log --force-reinstall 提供的类和方法 论文复现赛 在论文复现赛中&#xff0c;主要用到的类如下所示。 ReprodLogger 功能&#xff1a;记录和保存…

MySQL免安装版安装教程

官网下载安装包 MySQL :: Download MySQL Community Server (Archived Versions) 选择mysql版本下载 安装配置MySQL 将下载完的Mysql安装包解压到指定目录 打开windos系统的cmd&#xff0c;以管理员身份运行 进入mysql文件夹中的bin目录 安装MySQL的服务mysqld --install 初…

代码随想录刷题第33天

第一题是k次取反后求数组最大和https://leetcode.cn/problems/maximize-sum-of-array-after-k-negations/description/&#xff0c;使用了两次贪心策略&#xff1a;第一次是优先将绝对值大的负数进行取反&#xff0c;若负数取完后&#xff0c;取反次数仍有剩余&#xff0c;则将…