const和指针的结合

目录

易错知识点

const和指针的结合

const和一级指针的结合

正误转换

巧用技巧

const是否参与类型

const和二级指针的结合

正误转换

巧用技巧

温故知新


易错知识点

1、常量不能作为左值,防止直接修改常量的值

2、不能将常量的地址泄露给普通指针或普通引用变量,防止间接修改常量的值

// 关于易错知识点第2点
// 不能将常量的地址泄露给普通指针或普通引用变量,防止间接修改常量的值
const int a = 10;
const int * p = &a; // 正确写法!
// int * p = &a;       // 错误写法!
// int * const p = &a; // 错误写法!
	// 以下写法均正确!int a = 1;int * p1 = &a;const int * p2 = &a;int const * p3 = &a;int * const p4 = &a;const int * const p5 = &a;int const * const p6 = &a;

const和指针的结合

1、const修饰离它最近的类型

2、注意区分const修饰的类型和const修饰的表达式:

除去const和它修饰的类型,剩余部分就是const修饰的表达式(详见以下代码段)

3、如果const右边没有指针*,那么const不参与类型

const和一级指针的结合

正误转换

// 正确转换
// 1
const int *  <=  int *// 2
int * const *  <=  int * *
// const因它右边*而参与类型
// 因此可将int * const *  <=  int * *看做是const *  <=  *
// 所以是正确转换// 错误转换
// 1
int *  <=  const int *// 2
int * *  <=  int * const *
// const因它右边*而参与类型
// 因此可将int * *  <=  int * const *看做是*  <=  const *
// 所以是错误转换

巧用技巧

// const和一级指针的结合
// 巧用“除去const和它修饰的类型,剩余部分就是const修饰的表达式”技巧// 1
const int * p;
// const int * p;与int const * p;等价
// const修饰的类型为int,修饰的表达式为*p
// *p的值不能被修改,p的值可以被修改
// 指针p可以指向其它内存,但不能通过指针p修改内存的值// 2
int const * p;
// int const * p;与const int * p;等价
// const修饰的类型为int,修饰的表达式为*p
// *p的值不能被修改,p的值可以被修改
// 指针p可以指向其它内存,但不能通过指针p修改内存的值// 3
int * const p;
// *不能单独作为类型,const修饰的类型为int *,修饰的表达式为p
// p的值不能被修改,*p的值可以被修改
// 可以通过指针p修改内存的值,但指针p不能指向其它内存// 4
const int * const p;
// const int * const p;与int const * const p;等价
// const int * const p;相当于const int * p;和int * const p;的综合
// 前const修饰的类型为int,修饰的表达式为*p
// 后const修饰的类型为int *,修饰的表达式为p
// 不能通过指针p修改内存的值,指针p也不能指向其它内存// 5
int const * const p;
// int const * const p;与const int * const p;等价
// int const * const p;相当于int const * p;和int * const p;的综合
// 前const修饰的类型为int,修饰的表达式为*p
// 后const修饰的类型为int *,修饰的表达式为p
// 不能通过指针p修改内存的值,指针p也不能指向其它内存// 总结
// 第一类:const int * p;与int const * p;等价
// 第二类:int * const p;
// 第一类和第二类综合形成第三类:
// const int * const p;与int const * const p;等价

const是否参与类型

// const和一级指针的结合
// 关于“3、如果const右边没有指针*,那么const不参与类型”#include<iostream>
#include<typeinfo>
using namespace std;int main()
{int * p1 = nullptr;int * const p2 = nullptr;cout << "int * p1定义的p1的类型为" << typeid(p1).name() << endl;cout << "int * const p2定义的p2的类型为" << typeid(p2).name() << endl;cout << "总结:如果const右边没有指针*,那么const不参与类型" << endl;cout << "-------------------------------------------" << endl;const int * p3 = nullptr;cout << "const int * p3定义的p3的类型为" << typeid(p3).name() << endl;cout << "总结:如果const右边有指针*,那么const参与类型" << endl;return 0;
}

const和二级指针的结合

正误转换

// 错误转换
int * *  <=  const int * *
const int * *  <=  int * *
// 关于const int * *  <=  int * *是错误转换的说明// 例如,有如下错误代码:
int a = 1;
int * p = &a;
const int * * q = &p;
// 假如以上代码逻辑成立,
// 那么*q为指向const int类型的指针,那么可以写如下代码:
const int b = 2;
*q = &b;
// 值得注意的是,*q和p属于同一内存
// 而p是int *类型,是一个普通指针
// 这违背易错知识点第2点“不能将常量的地址泄露给普通指针或普通引用变量,防止间接修改常量的值”
// 所以const int * *  <=  int * *是错误转换
// 同理,int * *  <=  const int * *是错误转换

巧用技巧

// const和二级指针的结合
// 巧用“除去const和它修饰的类型,剩余部分就是const修饰的表达式”技巧// 1
const int * * q;
// const修饰的类型为int,修饰的表达式为**q
// q能被赋值
// *q能被赋值
// **q不能被赋值// 2
int * const * q;
// *不能单独作为类型,const修饰的类型为int *,修饰的表达式为*q
// q能被赋值
// *q不能被赋值
// **q能被赋值// 3
int * * const q;
// const修饰的类型为int * *,修饰的表达式为q
// q不能被赋值
// *q能被赋值
// **q能被赋值// 总结
// 第一类:const int * * q;
// 第二类:int * const * q;
// 第三类:int * * const q;

温故知新

1、注意理解前文的正确转换和错误转换!

2、如果const右边没有指针*,那么const不参与类型

// 1
int a = 1;
const int * p = &a;
// const int *  <=  int *,正确!
int * q = p;
// int *  <=  const int *,错误!// 2
int a = 1;
int * const p = &a;
// int *  <=  int *,正确!
int * q = p;
// int *  <=  int *,正确!// 3
int a = 1;
int * const p = &a;
// int *  <=  int *,正确!
int * const q = p;
// int *  <=  int *,正确!// 4
int a = 1;
int * const p = &a;
// int *  <=  int *,正确!
const int * q = p;
// const int *  <=  int *,正确!// 5(注意联系6和7)
int a = 1;
int * p = &a;
// int *  <=  int *,正确!
const int * * q = &p;
// const int * *  <=  int * *,错误!// 6(注意联系5和7)
int a = 1;
const int * p = &a;
// const int *  <=  int *,正确!
const int * * q = &p;
// const int * *  <=  const int * *,正确!// 7(注意联系5和6)
int a = 1;
int * p = &a;
// int *  <=  int *,正确!
const int * const * q = &p;
// const int * const *  <=  int * *,正确!// 8
int a = 1;
int * p = &a;
// int *  <=  int *,正确!
int * const * q = &p;
// int * const *  <=  int * *
// 相当于const *  <=  *,正确!// 9
int a = 1;
int * p = &a;
// int *  <=  int *,正确!
int * * const q = &p;
// int * *  <=  int * *,正确!// 10
int a = 1;
int * const p = &a;
// int *  <=  int *,正确!
int * * q = &p;
// 注意!注意!
// int * *  <=  int * const *
// 相当于*  <=  const *,错误!// 11
int a = 1;
const int * p = &a;
// const int *  <=  int *,正确!
int * const * q = &p;
// 注意!注意!
// int * const *  <=  const int * *
// 相当于const *  <=  *和int *  <=  const int *
// const *  <=  *,正确!
// int *  <=  const int *,错误!
// 综上,int * const *  <=  const int * *,错误!

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

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

相关文章

k8s基础

k8s基础 文章目录 k8s基础一、k8s组件二、k8s组件作用1.master节点2.worker node节点 三、K8S创建Pod的工作流程&#xff1f;四、K8S资源对象1.Pod2.Pod控制器3.service && ingress 五、K8S资源配置信息六、K8s部署1.K8S二进制部署2.K8S kubeadm搭建 七、K8s网络八、K8…

大语言模型(LLM)与 Jupyter 连接起来了

现在&#xff0c;大语言模型&#xff08;LLM&#xff09;与 Jupyter 连接起来了&#xff01; 这主要归功于一个名叫 Jupyter AI 的项目&#xff0c;它是官方支持的 Project Jupyter 子项目。目前该项目已经完全开源&#xff0c;其连接的模型主要来自 AI21、Anthropic、AWS、Co…

Spring AoP 详解

目录 一、概述二、Spring AOP 和 AspectJ AOP 的区别三、AspectJ 定义的通知类型四、多个切面的执行顺序控制方法 一、概述 AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关&#xff0c;却为业务模块所共同调用的逻辑或责任&#xff08;例如事务处理、日志…

【c语言】指针进阶(超详细)

文章目录 ✈ 指向函数指针数组的指针&#x1f4cc;指向函数指针数组的指针的定义&#x1f4cc;指向函数指针数组的数组指针的使用 ✈回调函数&#x1f4cc; 回调函数的定义&#x1f4cc; 回调函数的使用 ✈qsort函数&#x1f4cc; qsort函数的作用&#x1f4cc;qsort函数的定义…

【Spring Boot】构建RESTful服务 — 使用Swagger生成Web API文档

使用Swagger生成Web API文档 高质量的API文档在系统开发的过程中非常重要。本节介绍什么是Swagger&#xff0c;如何在Spring Boot项目中集成Swagger构建RESTful API文档&#xff0c;以及为Swagger配置Token等通用参数。 1.什么是Swagger Swagger是一个规范和完整的框架&…

Docker desktop使用配置

1. 下载安装 https://www.docker.com/ 官网下载并安装doker desktop 2. 配置镜像 &#xff08;1&#xff09;首先去阿里云网站上进行注册&#xff1a;https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors &#xff08;2&#xff09;注册完成后搜索&#xff1a;容…

go入门实践四-go实现一个简单的tcp-socks5代理服务

文章目录 前言socks协议简介go实现一个简单的socks5代理运行与压测抓包验证 前言 SOCKS是一种网络传输协议&#xff0c;主要用于客户端与外网服务器之间通讯的中间传递。协议在应用层和传输层之间。 本文使用先了解socks协议。然后实现一个socks5的tcp代理服务端。最后&#…

opencv实战项目 手势识别-手部距离测量

手势识别系列文章目录 手势识别是一种人机交互技术&#xff0c;通过识别人的手势动作&#xff0c;从而实现对计算机、智能手机、智能电视等设备的操作和控制。 1. opencv实现手部追踪&#xff08;定位手部关键点&#xff09; 2.opencv实战项目 实现手势跟踪并返回位置信息&…

MySQL索引和事务

目录 索引的作用 与 概念 MySQL有哪几种索引类型 如何提高查找效率 聚簇索引与非聚簇索引 覆盖索引 索引的优点和缺点 索引的一些基本操作 索引优化 B树、B树、Hash、红黑树的区别 B树与B树的区别 MySQL为什么使用B树作为索引 联合索引中的顺序 MySQL的最左前缀原…

第三节:在WORD为应用主窗口下关闭EXCEL的操作(1)

【分享成果&#xff0c;随喜正能量】夏日里的遗憾&#xff0c;一定都会被秋风温柔化解。吃素不难&#xff0c;难于不肯捨贪口腹之心。若不贪口腹&#xff0c;有何吃素之不便乎。虽吃华素&#xff0c;不吃素日&#xff0c;亦须少吃。以一切物类&#xff0c;皆是贪生怕死&#xf…

Spring Boot集成Mybatis Plus通过Pagehelper实现分页查询

文章目录 0 简要说明Pagehelper1 搭建环境1.1 项目目录1.2 项目搭建需要的依赖1.3 配置分页插件拦截器1.4 源代码启动类实体类数据层xml映射文件业务层业务层实现类控制层接口配置swagger请求体 2 可能出现的疑问或者问题2.1 关于total属性疑问2.2 分页不生效问题 3 案例说明3.…

Dynamic Web TWAIN Crack

Dynamic Web TWAIN Crack 文件编辑 提供 GUI 和非 GUI 图像编辑器 内置基本图像编辑界面&#xff0c;如旋转、裁剪、镜像、翻转、擦除和更改图像大小 支持向图像添加彩色矩形 支持文字注释 提供图像交换功能 支持清除图像的指定区域并用颜色填充清除的区域 内置变焦 提供多图像…

VUE3组件

组件基础 {#components-basics} 组件允许我们将 UI 划分为独立的、可重用的部分&#xff0c;并且可以对每个部分进行单独的思考。在实际应用中&#xff0c;组件常常被组织成层层嵌套的树状结构&#xff1a; 这和我们嵌套 HTML 元素的方式类似&#xff0c;Vue 实现了自己的组件…

pyscenic分析:视频教程

我们之前更新过pyscenic的教程&#xff1a;pySCENIC单细胞转录因子分析更新&#xff1a;数据库、软件更新。我们也说过&#xff0c;我们号是放弃R语言版的SCENIC的分析了&#xff0c;因为它比较耗费计算资源和时间&#xff0c;所以我们的单细胞转录因子分析教程都是基于pysceni…

JavaScript算法【入门】

作者&#xff1a;20岁爱吃必胜客&#xff08;坤制作人&#xff09;&#xff0c;近十年开发经验, 跨域学习者&#xff0c;目前于海外某世界知名高校就读计算机相关专业。荣誉&#xff1a;阿里云博客专家认证、腾讯开发者社区优质创作者&#xff0c;在CTF省赛校赛多次取得好成绩。…

openocd调试esp32(通过FT232H)

之前在学习ESP32&#xff0c;其中有一部分课程是学习openocd通过JTAG调试程序的&#xff0c;因为我用的是ESP32-wroom&#xff0c;usb端口没有集成对应的usb转jtag的ft232&#xff0c;查了ESP32相关的资料&#xff08;JTAG 调试 - ESP32 - — ESP-IDF 编程指南 latest 文档 (es…

React如何配置env环境变量

React版本&#xff1a; "react": "^18.2.0" 1、在package.json平级目录下创建.env文件 2、在‘.env’文件里配置环境变量 【1】PUBLIC_URL 描述&#xff1a;编译时文件的base-href 官方描述&#xff1a; // We use PUBLIC_URL environment variable …

使用 PyTorch 逐步检测单个对象

一、说明 在对象检测任务中&#xff0c;我们希望找到图像中对象的位置。我们可以搜索一种类型的对象&#xff08;单对象检测&#xff0c;如本教程所示&#xff09;或多个对象&#xff08;多对象检测&#xff09;。通常&#xff0c;我们使用边界框定义对象的位置。有几种方法可以…

netty基础与原理

Netty线程模型和Reactor模式 简介&#xff1a;reactor模式 和 Netty线程模型 设计模式——Reactor模式&#xff08;反应器设计模式&#xff09;&#xff0c;是一种基于 事件驱动的设计模式&#xff0c;在事件驱动的应用中&#xff0c;将一个或多个客户的 服务请求分离&#x…

windows任务栏右下角不显示网络图标解决方法

1、背景 我运行windows诊断服务之后&#xff0c;然后重启了一把电脑&#xff0c;结果发现电脑无法上网了&#xff0c;进一步发现任务栏右下角的网络显示图标也没有了&#xff0c;网络状态显示也是一条横线。 几经折腾终于给解决了&#xff0c;遇到了不少坑&#xff0c;记录一…