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

指针和引用

指针

const和一级指针

判断const 修饰的常量
const修饰的量常出现的错误是:
1.常量不能再作为左值《=(不然会直接修改常量的值)

const int a=10;
a=20;//尝试直接修改常量,错误

2.不能再把常量的地址泄露给一个普通的指针或者普通的引用变量(不然会间接的修改常量的值)

const int a=10;
int *p=&a;

//这样可以间接通过指针解引用方法修改内存a的值。
*p=20;

//正确的定义方式为
 const int *p=&a;

C++的语言规范:const修改的是离它最近的类型(去掉类型(如int和int *,并且满足一个最少原则,如果是int *和int中选择,那么一定是int),去掉类型后其修饰的表达式就是不能改变的,即const)

指针指向地址的内容不能被修改

int a=10;
int b=100;
const int *p=&a;
int const *p=&a; //这个与上面那句是等效的,int 在const 左右均不影响

//这里去掉最近的类型,即 int ,const修饰的是*p,表示*p不能被修改。
*p=20; //错误
p=&b; //正确

//指针p可以指向任意不同的int类型的内存,但不能通过指针间接修改指向的内存的值

指针指向地址不能被修改

int a=10;
int b=100;

int * const p=&a; //const 最近且满足最少原则的类型应该是int *,则其修饰的表达是为 p,表示p不能被修改

//指针p是常量,不能再指向其他内存,但是可以通过指针解引用修改指向内存的值
p=&b; //错误
*p=20; //正确

注意:const 如果右边没有指针*的话,const是不参与类型的。

int * q1=nullptr;
int *const q2=nullptr;

int const *q3=nullptr;
//这里q1和q2的类型都是 int *; q3的类型是int const *;

const和二级指针

int a=10;
int *p=&a;
//三种情况

//情况1
const int **q=p; //修饰的是 const **q,即不能通过q二级指针解引用修改q指向的一级指针指向的变量的值,**q不能被赋值

//情况2
int *const *q=p; //修饰的是 const *q,*q指向的一级地址的值不能被改变,*q不能被赋值

//情况3
int ** const q=p; //修饰的是const q,即q本身不能改变,q不能被赋值

总结 const 和 指针的类型转换公式

int * <<<=== const int *  ;//是错误的!!!
const int * <<<=== int *;  //是正确的!!!


int ** <<<=== const int **; //是错误的!!!
const int **<<<=== int **; //是错误的!!!
//在二级指针甚至多级指针中,两边都要有const 才算正确;

int ** <<<===int * const *;//是错误的!!!
//前面说到,const只负责其右边的类型构造,上面可以简化为
int * <<<===int  const *; //判断错误

int *const *<<<=== int **;  //是正确的!!!
//简化为 int const *<<<=== int *; 

错误样例

int a=10;
const int *p=&a;
int *q=p;//这里 int *<<<===const int *,不匹配
int a=10;
int *p=&a;
const int **q=&p; //const int ** <<<=== int  **,不匹配,&p取地址加一个*
int a=10;
int *const p=&a;  //p为int *,const 只在其右边有指针时起作用;
int **q=&p;//因为这有一个取地址操作,则 int ** <<<===int *const *,不匹配

int a=10;
const int *p=&a;
int *const*q =&p; //int *const *<<<===const int **,左边是const 与一级指针结合,右边是const 与二级指针结合,不匹配(我是怎么理解的,不知道有没有更好的解释)

引用

定义

引用是一种更安全的指针。

int a=10;
int *p=&a;
int &p=a;
//如果不会定义引用,可以先写出指针形式,然后用等号右边的&符号覆盖等号左边的*,代码如上

//定义一个引用变量,来引用array数组
int array[5]={};
int *p=array;  //4字节,指向array第一个数组内存
int (*q)[5]=&array;//5字节,指向array数组的指针,对应的引用应该这样写
int (&q) [5]=array;

1.引用时必须初始化的,指针可以不用初始化
2.引用只有一级引用,没有多级引用;指针可以有一级指针,也可以有多级指针。
3.定义一个引用变量和定义一个指针变量,其汇编指令是一模一样的;通过引用变量修改所引用内存的值,和通过指针解引用修改指针指向的内存的值,其底层汇编指令也是一模一样的。

左值引用和右值引用

左值引用
左值引用指的是引用的是有内存,有名字,其值可以修改的

//语法 T &

int a=10;
int &b=a;

//特殊的左值引用
const int &b=20;

右值引用
右值引用是是没有内存,没有名字的,如立即数20.

//语法 T &&

//c++11提供了右值引用
int &&c =20;

总结

const int &b=20;
int &&c =20;

//这两个代码底层原理都是一样的
//1.产生临时变量存储该常数
//2.然后直接引用临时量

int  temp=20;
int &b=temp;

指针、引用和const的结合

//在内存的ox0018ff44处写一个4字节的10

int * const &p=(int *) 0x0018ff44  //特殊的左值引用以实现常量引用
*p=10

错误样例

int a=10;
int *p=&a;
const int *&q=p; //转换成const int **q=&p,则const int ** <<<===int **,不匹配


int a=10;
int *const p=&a;
int *&q=p; //转换成int **q=&p; 即 int **<<<===int *const *,不匹配

int a=10;
const int *p=&a;
int *&q=p; //转换成int **q=&p; 即int **<<<===const int **,错误

int a=10;
int *p=&a;
const int *&q=p; //转换成const int **q=&p; 即cosnt int **<<<===int **,错误

其他

注意[]和()的优先级高于*。

数组指针和指针数组

数组指针

//数组类型的指针

//指针有各种类型 ,int *,float *
//将数组当作一种数据类型,定义一个指向数组的指针

int a=10;
int *pa=&pa;

int arr={1,2,3};
int (*pa) []=&arr;
//表明这是一个指针,并且指向一个数组,这个数组中的类型是int 类型

指针数组

int a=10,b=20,c=30;
int *arr[]={&a,&b,&c};
//arr先与[]结合,表示这是一个数组,并且这个数组的类型是int *

函数指针和指针函数

函数指针

//是一个指针,指向一个函数,函数返回类型是int 型
int (*fun) (int x);

指针函数

int *fun (int x)
//fun先与()结合,表示这是一个函数,返回类型为int *;

http://www.kler.cn/a/614870.html

相关文章:

  • 通过一个led点灯的demo来熟悉openharmony驱动编写的过程(附带hdf详细调用过程)
  • 聚合根的特性
  • JavaScript基础-navigator 对象
  • Docker 的实质作用是什么
  • 蓝桥杯省模拟赛 质因数之和
  • 视频AI赋能水利行业生态治理,水电站大坝漂浮物实时监测与智能预警方案
  • 【C++标准IO库】文件的输入输出
  • 机器视觉基础—高斯滤波
  • Pod 网络与 CNI 的作用
  • 【Go】数组
  • 如何低成本选择讯投QMT 的服务器/电脑,低成本运行?
  • Zynq + FreeRTOS 笔试题1
  • YOLOv8环境配置及依赖安装过程记录
  • Github 2025-03-28 Java开源项目日报Top10
  • ‌GraphRAG 知识图谱,设置适配阿里云百炼平台实战教程【上】
  • 第三卷:覆舟山决战(73-108回)正反人物群像
  • 前端常问的宏观“大”问题详解(二)
  • Unity编辑器功能及拓展(3) —[Attribute]特性
  • Scala 数组
  • IDEA如何设置以新窗口打开新项目