指针和引用的区别以及引用与指针基础

article/2025/10/3 0:56:49

1·引用:

引用(reference)为对象起了另外一个新的名字通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名:

int ival = 1024;int& refval = ival;int& refval2;//报错:引用必须被初始化

1.1为什么引用必须被初始化?

变量在初始化的过程中,初始值会被拷贝到新建的对象中。

定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用和它的初始对象绑定在一起,无法绑定到另外的一个对象,所以必须初始化

在这里举个例子,比如我们定义一个int 类型的变量并将它初始化为10,那么计算就会在内存当中分配一块内存空间,保存10整个值,给整个内从空间起了一个名字叫a,而b是对a的引用,所以相当与这块内存空间有两个名字,但其实说的是一回事

假设我们不给初始化的时候,那么就不知道它到底指的是哪里

引用并非对象,不分配内存空间,它只是为一个已经存在的对象所起的另外一个名字

O8hXTI.png

通过下面的代码测试我们来看下

O85wGV.png

我们在这里定义了一个引用之后,对其进行所有的操作都是在与之绑定的对象上进行的

为引用赋值,实际上是 把值赋给了与引用绑定的对象。获取引用的值,实际上是获取了与引用绑定对像的值。

	int ival = 1024;int& refval = ival;//int& refval2;//报错:引用必须被初始化//refval = 2;//将2赋值给refval指向的对象,此处即是复赋值给了 ival//正确:refval绑定到了那个与refval的对象上,这里即ivalint& refval3 = refval;//利用绑定的对象来初始化其它变量int i = refval;

O8oKc8.png

1.2引用的定义

允许在一条语句中定义多个引用,其中每个引用标识符都必须以符号&开头

//定义了一个变量i与i2并对其初始化为  1024与2048int i = 1024, i2 = 2048;//定义了 一个引用 并将其与i进行对应的绑定,定义了一个变量r2并将i2的值赋给它 i=1024,r2=2048int& r = i, r2 = i2;//定义了一个变量i3,定义了一个引用绑定i3 ri=1024int i3 = 1024, & ri = i3;//定义了2个引用,分别绑定了i3,和i2  r3=1024,r4=2048int& r3 = i3, & r4 = i2;

O8TWin.png

1.3引用的注意事项

  1. 左值引用不能够引用一个常量,必须为一个对象
  2. 引用的类型必须一致
int & r = 4;//error 引用不能够引用一个常量double x = 3.14;int& m = x;// error 引用的类型必须一致

O87rf1.png

O875tA.png

1.4引用的几个小练习

1·4.1 一下是否合法

	int ival = 1.01;//合法定义了一个整形变量,但初始值给了一个浮点型,所以这里会出现数据丢失现象int& rval1 = 1.01;//左值引用不能够引用一个常量int& rval2 = ival;//合法,因为引用了一个对象,且类型一致int& rval3;//错误引用必须进行对应的初始化

1·4·2 以下哪些赋值时不合法的?为什么?哪些时合法的?它们执行了哪些操作

在这里我错了,如果高进度引用低精度是可以的,但低进度赋值和引用高精度是不可以的

int i = 0, & r1 = i;double d = 0, & r2 = d;//合法r2是对d的引用,此时d的值为3.14159r2 = 3.14159;//r2=r1是将r1的值赋值给r2,因为r1是int类型,所以此时会进行强转成double d 和r2=1.00000r2 = r1;//i是一个int 类型,所以在之类 i=3--在这里我错了,如果高进度引用低精度是可以的,但低进度赋值和引用高精度是不可以的i = r2;//r1是一个引用,=d 会造成数据丢失,变成3r1 = d;

O8qf7F.png

O8LY4J.png

O8Lag1.png

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-trBtVhCC-1652102162293)(C:/Users/kexib/AppData/Roaming/Typora/typora-user-images/image-20220509113356061.png)]

1·4·2执行下面的代码将会输出什么样的结果

int i, & r1 = i;i = 5; //这句执行完 i=5,r1=5r1 = 10;//这句执完2者都为10;

O8OVr6.png

O8OmVO.png

2·指针

**指针(pointer)**是“指向的另外一种类型的复合类型”

  1. 指针本身就是一个对象,允许对指针进行赋值和拷贝
  2. 在生命周期内它可以指向几个不同的对象
  3. 指针在定义时无需初始化,如果不进行初始化,也将拥有一个随机值

2·1指针的定义

将声明符写成 *d的形式,d为变量名。

*如果在一条语句中定义了多个指针变量,则需要在每个前面都加上 **

OGwmgx.png

我们在这里可以清晰的看到,n,x都是指针类型,m是整形

在定义指针的时候还有一点要注意那就是不能够定义指向引用的指针因为引用时不是对象没有地址,同时左引用也不能引用常量

2·2指针获取对象的地址

指针存放某个对象的地址,想要获取该地址,需要使用取地址符(操作符 &)

2.3.1指针的大小

  1. 在32位操作系统下,所有的指针都只占4个字节
  2. 在64位操作系统下,所有的指针都占8个字节
为什么指针的大小会是这样呢?

因为在计算机当中,只有整数寄存器次啊可以存放指针(内存数据的地址)

在32位操作系统当中,地址的大小是32bit,因此其最大寻址空间位2^32,也就位4个字节

在32位操作系统当中,地址的大小是64bit,因此其最大寻址空间位2^64,也就位8个字节

在32位操作系统当中,地址的大小是32bit,因此其最大寻址空间位2^32,也就位4个字节

我们用代码来验证一下
  1. 在64位操作系统下

    OJefPJ.png

    2·在32位操作系统下

    OJeTr6.png

2.3指针值

  1. 指向一个对象
  2. 指向紧邻对象所占空间的下一个位置
  3. 空指针,意味着没有指向任何对象
  4. 无效指针,也就时上述情况之外的其他值

2.4利用指针访问对象

如果指针指向了一个对象,则允许他通过 **解引用符(*)**来访问该对象

2.5&与*这样的符号,既能够作用于表达式里的运算符,也能够作为声明的一部分出现,符号的上下文决定了符号的意义

	int i = 42;int& r = i;//&紧随类型名出现,因此是声明的一部分,r是一个引用int* p;//*紧随类型名出现,p是一个指针p = &i;//&在表达式中为取地址符*p = i;//* 出现咱表达式中,是一个解引符int& r2 = *p;//&是声明的一部分,*是一个解引符

2.6空指针

空指针(null pointer)不指向任何对象,在试图使用一个指针指针代码首先要检查其是否为空

生成空指针的几种办法

	int* p1 = nullptr;//在C11的标准下,使用nullptr来初始化空指针,所以最好使用nullptr来进行初始化int* p2 = 0;//需要首先调用#include <cstdlib>int* p3 = NULL;
	//错误不能把int 变量直接赋值给指针int zer0 = 0;int* p1 = zer0;

2.7 赋值和指针

	int i = 42;int* pi = 0;//pi被初始化,但没有指向任何对象int* pi2 = &i;//pi2被初始化,存i的地址int* pi3;//定义于内存块中,pi3无法确定pi3 = pi2;//pi3和pi2指向同一个对象pi2 = 0;//不指向任何对象了

赋值永远改变的是等号左侧的对象

pi=&ival;//pi的值被改变,指向了ival;
*pi=0;//ival的值被改变,指针p并没有变

任何非0指针对应的条件都是true

	int ival = 1024;int* p = 0;int* p2 = &ival;if(p)//为falseif(p2)//为true

2.8 void * 指针

特殊类型的指针,可以存放任意对象的地址 *但不能够直接操作void 指针指向的对象,因为并不知道所指的对象是什么类型

	double obj = 3.14, * pd = &obj;void* pv = &obj;//pv 可以保存任何类型的指针pv = pd;*pv = 5.89;//error 不能够指针操作pv 指向的对象

2.9对应练习题

  1. 编写代码分别更改指针的值,以及指针所指向对象的值

    	int i = 0, *p = &i;int x = 10;*p = 5;//将i的值改为5p = &x;//将p指向的地址改为x的地址
    

OJdwid.png

  1. 请叙述下面代码的作用

    	int i = 42;int* p1 = &i;//p1指向i*p1 = *p1 * *p1;//修改i的指为 42*42	
    

    2.下述哪些是非法的?

	int i = 0;double* p = &i;//错误int 类型不能够初始化double类型的实体int* pi = i;//int 类型的变量不能够初始化其指针int* p = &i;

​ 3.假设p是一个int 类型的指针,请阐述下面的含义

if(p);//p不为一个空指针则为true
if(*p)//p所指对象的值部位0则为true

​ 4·给定一个指针p,是否知道它指向了一个合法的对象吗?如果能,请说你的思路

如果不是一个void * ,就可以,首先编译器会帮助我们进行判断,并给出提示错误。其次我们可以尝试输出指针所指对象的指。非法时编译器会报错,但如果是一个void 指针,我们没有办法访问内存空间所存的对象,也就无法判断其是否指向了一个合法的对象

​ 5.在下面这段代码中,为什么p合法而lp非法

int i=42;
void *p=&i;
long *lp=&i;
//因为void 指针可以存放任意类型的地址 而long 指针只能存放long 类型的地址

一个int 类型的指针,请阐述下面的含义

if(p);//p不为一个空指针则为true
if(*p)//p所指对象的值部位0则为true

​ 4·给定一个指针p,是否知道它指向了一个合法的对象吗?如果能,请说你的思路

如果不是一个void * ,就可以,首先编译器会帮助我们进行判断,并给出提示错误。其次我们可以尝试输出指针所指对象的指。非法时编译器会报错,但如果是一个void 指针,我们没有办法访问内存空间所存的对象,也就无法判断其是否指向了一个合法的对象

​ 5.在下面这段代码中,为什么p合法而lp非法

int i=42;
void *p=&i;
long *lp=&i;
//因为void 指针可以存放任意类型的地址 而long 指针只能存放long 类型的地址

总结. 说明指针和引用的主要区别

  1. 指针变量存放某个对象的地址;引用则是对象的别名

  2. 程序为指针变量分配存储区;引用不会分配内从区域

  3. 解引用时指针需要加*;而引用不需要

  4. 指针可以指向不同对象的地址;而引用只能绑定初始化对象的地址,之后无法改变

  5. 指针变量可以初始化为空;而没有所谓的空引用

  6. 指针在作为形参的时候需要判断其合法性是否为空;引用不需要

  7. 对指针sizeof()得到的是指针的大小;对引用则是变量的大小

  8. 指针的化可以由2级指针,3级指针;而引用没有引用的引用

  9. ++引用与++指针操作不一样

    1. 引用操作直接反应到所引用的实体
    2. 指针++,则指向下一个对象的地址,不更改其所指的内容
  10. 不可以对函数中的局部变量或对象以引用或指针方式返回

    1. 如果返回的是指针时,要成为全局变量次啊可以–标识符的实体不受函数的影响

      为什么会是这样?

      #include<iostream>
      using namespace std;
      int * val(int a, int b) {int c = a + b;int* p = &c;return p;
      }
      int main() {int* p = val(2,4);return 0;
      }
      

      OJa3DS.png
      OJavKf.png

//当我将C改成全局的时候就不会出现这种情况
int c;
int * val(int a, int b) {c = a + b;int* p = &c;return p;
}
int main() {int* p = val(2,4);return 0;}

在这里插入图片描述


http://chatgpt.dhexx.cn/article/pI7mlniG.shtml

相关文章

C++中指针和引用的区别(超详细)

指针和引用主要有以下区别&#xff1a; 引用必须被初始化&#xff0c;但是不分配存储空间。指针不声明时初始化&#xff0c;在初始化的时候需要分配存储空间。 引用初始化后不能被改变&#xff0c;指针可以改变所指的对象。 不存在指向空值的引用&#xff0c;但是存在指向空值的…

c++:指针和引用的区别

目录 前言&#xff1a; 1、引用概念上是定义一个变量的别名&#xff0c;而指针是存储一个变量的地址。 2、引用在定义时必须要初始化&#xff0c;但是指针没有要求。 3、引用在初始化时引用一个实体后&#xff0c;就不能再引用其他实体&#xff0c;因为其本质是一个指针常量…

C++中指针和引用的区别

1.指针和引用的定义和性质区别&#xff1a; &#xff08;1&#xff09;指针&#xff1a;指针是一个变量&#xff0c;只不过这个变量存储的是一个地址&#xff0c;指向内存的一个存储单元&#xff1b;而引用跟原来 的变量实质上是同一个东西&#xff0c;只不过是原变量的一个别…

C++中的指针与引用

写在前面 指针和引用形式上很好区别&#xff0c;但是他们似乎有相同的功能,都能够直接引用对象&#xff0c;对其进行直接的操作。但是什么时候使用指针&#xff1f;什么时候使用引用呢&#xff1f;这两者很容易混淆,在此我详细介绍一下指针和引用&#xff0c;力争将最真实的一…

引用和指针概念及区别

一、引用和指针 指针&#xff1a;指针是一个特殊的变量&#xff0c;它里面存储的的数值为内存里的一个地址&#xff0c;通过*访问内存地址所指向的值 引用&#xff1a;引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内…

01背包.动态规划.c语言实现

二维dp数组01背包 确定dp数组以及下标的含义 使用二维数组&#xff0c;即dp[i][j] 表示从下标为[0-i]的物品里任意取&#xff0c;放进容量为j的背包&#xff0c;价值总和最大是多少 2.递推公式&#xff1a;dp[i][j]dp[i-1][j-weight]value[i] dp[i][j]dp[i-1][j] 3.数组初始…

【动态规划】背包问题

注意&#xff1a;for j in range(1&#xff0c;m1):是枚举所有的情况&#xff0c;不用一一判断放入物品后背包容量减少后j的变化。为什么从1开始&#xff0c;因为0已经写出来了&#xff0c;即dp[i-1][j]dp[i-1][j-0*a[i-1]]0*v[i-1]。 01背包无价值 dp定义&#xff1a;前i项物…

动态规划——背包问题(01背包问题)

动态规划——背包问题&#xff08;01背包问题&#xff09;01背包问题(求最大价值)&#xff1a;问题优化01背包问题(求方案数)&#xff1a; 动态规划——背包问题&#xff08;01背包问题&#xff09; 01背包问题(求最大价值)&#xff1a; 有N件物品和一个最多能背重量为W的背包…

动态规划:关于01背包问题 I

动态规划&#xff1a;关于01背包问题&#xff0c;你该了解这些&#xff01; 对于面试的话&#xff0c;其实掌握01背包&#xff0c;和完全背包&#xff0c;就够用了&#xff0c;最多可以再来一个多重背包。 如果这几种背包&#xff0c;分不清&#xff0c;我这里画了一个图&…

c++ 动态规划-01背包

动态规划 - 01背包问题 1.使用递归遍历(穷举)求解&#xff1a; 01背包问题&#xff1a;给定 n 种物品和一个重量(容量)(限定条件)为 w 的背包,物品 i 的重量是 wi,其价值为 vi。(每种物品只有一个)问:如何选择装入背包的物品,使得装入背包中的物品的价值最大。 //VC6.0------…

动态规划——01背包问题(C++实现)

题目描述&#xff1a; 解题思路&#xff1a; 整体思路&#xff1a; 利用动态规划&#xff0c;其目的就是将原问题分解成几个子问题&#xff0c;通过求解简单的子问题&#xff0c;把原问题给解决&#xff0c;就比如斐波那契数列方程&#xff1a; f[i]f[i-1]f[i-2]; 动态规划的…

动态规划总结三01背包问题

01背包问题一般是利用动态规划进行解题的&#xff0c;这里通过leetcode1049来讲解01背包的解题思路以及如何对01背包应用题目转换和理清思路 01背包问题&#xff1a; 这里借用学习公众号代码随想录的一张图来说明背包问题的种类 对于面试的话&#xff0c;其实掌握01背包&…

dp 动态规划 01背包问题 Python

参考学习网址&#xff1a; https://www.bilibili.com/video/av33930433?fromsearch&seid10637513335818789097 https://www.cnblogs.com/anzhengyu/p/11408466.html 问题描述&#xff1a; 给定 n 件物品&#xff0c;物品的重量为 w[i]&#xff0c;物品的价值为 v[i]。现…

Python3使用动态规划处理01背包问题

文章目录 视频教程讲解题目介绍题解1&#xff1a;二维列表题解2&#xff1a;一维列表&#xff08;滚动数组&#xff09;延伸阅读 视频教程讲解 【Python算法系列】动态规划2-01背包问题&完全背包问题【Python算法实战】背包问题 题目介绍 原题链接&#xff1a;NC145 01背…

算法 动态规划 01背包问题

01背包 问题分析代码实现从前往后拿&#xff0c;递归实现非递归实现非递归实现&#xff0c;自上向下填充 允接上一文章内容&#xff1a; 算法 动态规划: link. 问题分析 按照普通思维&#xff0c;首先想到应该为贪心算法&#xff0c;也就是计算每个物品重量价值比&#xff0c;…

【动态规划】01背包问题

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位喜欢写作&#xff0c;计科专业大二菜鸟 &#x1f3e1;个人主页&#xff1a;starry陆离 &#x1f552;首发日期&#xff1a;2022年5月16日星期一 &#x1f30c;上期文章&#xff1a;【动态规划】最长上升子序列 &#x1f4…

01背包问题:图表法带你快速理解动态规划解决01背包问题 附C++源码

0-1背包问题 所谓0-1背包问题&#xff0c;也就是给你一个重量为M的背包和n种物品&#xff0c;每种物品有一定的重量和价值&#xff0c;在每种物品均可装入背包1次或不装入&#xff08;不能仅装入物品的一部分&#xff09;且不超过背包载重量的前提下&#xff0c;问你怎样选择物…

动态规划——0/1背包问题(全网最细+图文解析)

✨动态规划——0/1背包问题(全网最细图文解析) 作者介绍: &#x1f393;作者:青花瓷✨ &#x1f440;作者的Gitee:代码仓库 &#x1f4cc;系列文章推荐: ✨1.数据结构与算法—算法篇之动态规划(一) ✨2.【Java刷题特辑第一章】——【点进来花两把游戏的时间学习晚上睡觉都踏实了…

【动态规划】01背包问题(通俗易懂,超基础讲解)

问题描述 有n个物品&#xff0c;它们有各自的体积和价值&#xff0c;现有给定容量的背包&#xff0c;如何让背包里装入的物品具有最大的价值总和&#xff1f; 为方便讲解和理解&#xff0c;下面讲述的例子均先用具体的数字代入&#xff0c;即&#xff1a;eg&#xff1a;numbe…

java事务和分布式事务详解

目录 事务问题 1 Java事务的类型 2 spring事务实现源码分析 事务问题 面试经常会问到分布式锁、分布式事务、SOA 服务化、分布式系统等业务、架构的问题和解决方案&#xff0c;工作中接触的业务方面事关金融&#xff0c;也需要解决一些类似的业务问题&#xff0c;所以总结…