【跟学C++】C/C++必学知识——指针【番外2】


 ============================ 【说明】 ===================================================
  大家好,本专栏主要是跟学C++内容,自己学习了这位博主【 AI菌】的【C++21天养成计划】,讲的十分清晰,适合小白,希望给这位博主多点关注、收藏、点赞。
  主要针对所学内容,通过自己的理解进行整理,希望大家积极交流、探讨,多给意见。后面也会给大家更新,其他一些知识。若有侵权,联系删除!共同维护网络知识权利!
 =======================================================================================

1、什么是指针

  学习C或C++,大家最为困惑的还是指针这个概念,想必大家一开始脑海中的指针可能像这样:
在这里插入图片描述
  实际上,在C++中的指针相对更加抽象,学习时知道是指针,但又不知道怎么去用,作用如何?
  简单来讲,指针其实就是一种特殊的变量,特殊在于这种变量所存的值不像之前那样又是整数、浮点数啥的,而是内存地址。我们可以利用一张图形象表示:
在这里插入图片描述

  变量是要占内存空间的,图中Num是一个变量,存放地址为0x8865(本案例虚构地址),存放的值为15,pNum是一个指针,当然也是一个特殊变量,它存储的内容为0x8865,它自己也有存放地址0x8855,再往下就会涉及二级指针、多级指针。。。
  我们发现,指针和变量其实有相似之处,不同之处就是存放内容不一样。也可以发现,指针pNum中的存储地址(存放内容)就是变量Num的内存地址,因此,可以理解为,指针pNum时指向内存单元Num的特殊变量,说到这里,大致了解了什么是指针
  如果想更好利用指针,那么就要掌握最基本的四个部分
  (1) 如何声明指针
  (2) 如何使用& 符号获取变量地址
  (3) 如何使用指针存储地址
  (4) 如何使用* 符号访问指针指向的数据
  我们一一来解决上述四个问题。

1.1 如何声明指针

  指针也是特殊变量,它和变量也是需要声明一下,例如声明一个整型变量是这样的:

int Num=10;

  那么,声明指针时也是需要指明指针的类型,例如整型int,对应的是指针指向内存单元中存储的数的类型,例如:

int *pNum;

  之前提到过,声明变量时最好养成赋予初值的习惯,同样声明指针时,也要给一个初值,例如:

int Num=0;
int *pNum=Null;

:初始化为NULL的指针被称为NULL指针或空指针,空指针(即pAge) 是一个定 义在标准库中的值为零的常量。

1.2 如何使用&符号获取变量地址

  &称为引用运算符,关于引用可以看【跟学C++】C++的String类用法详解【番外1】。Num表示变量,那么&Num则获取该变量的内存地址。例如:

#include<iostream>
using namespace std;

int main() {
	int Num = 10;
	cout << "变量Num的地址为:" << hex << &Num << endl;
	return 0

在这里插入图片描述

1.3 如何使用指针存储地址

  前面了解了指针时用于存储内存地址的变量,也知道如何声明指针以及获取变量地址,我们可以利用指针来存储&获取的地址
在这里插入图片描述
  根据上图,我们通过一个案例,来获取变量地址,并传递给指针。

#include<iostream>
using namespace std;
int main() {
	int Num = 10;
	cout << "变量Num的地址为:" << hex << &Num << endl;
	int *pNum = &Num;
	cout << "指针pNum中存放地址(存储内容)为:" << hex << pNum << endl;
	return 0;
}

在这里插入图片描述
  结果可以发现,Num存放在内存中的地址和指针pNum中存放的地址,说明&可以获取Num的内存地址,并传递给指针pNum

1.4 如何使用* 符号访问指针指向的数据

  *称为解除引用运算符,我们可以通过*pNum来访问指针pNum包含的地址所存储的值(其实*pNum的值就是等于10,是值,而不是地址),例如:

#include<iostream>
using namespace std;
int main() {
	int Num = 10;
	cout << "变量Num的地址为:" <<  &Num << endl;
	int *pNum = &Num;
	cout << "指针pNum中存放地址(存储内容)为:" << pNum << endl;
	
	cout << "Num的值为:" << Num << endl;
	cout << "*pNum的值为:" << *pNum << endl;
	return 0;
}

在这里插入图片描述
  简单来说,指针pNum是指向变量Num对应的内存单元的,所以通过符号*就可以获得Num对应的值。

2、动态分配内存

  为了更好地管理程序占用的内存, C++提供了两个运算符: newdelete指针是包含内存地址的变量,在高效分配内存面扮演了重要的色

2.1 动态分配内存和释放内存

  使用new来分配内存块,new将返回指向一个指针,指向一个分配的内存。例如使用new为整型int分配内存:

int *pNum=new int;

  若为多个元素分配内存时:

int *pNum=new int[50];

  注意new在分配内存时,并不是所有要求都能满足,要看系统状态以及内存资源的可用性。
  我们分配内存后,如何使用完后,都要进行释放,例如:

1.单个元素
int *pNum=new int;
----程序----
delete pNum;

2.多个元素
int *pNum=new int[50];
----程序----
delete[] pNum;

  注意:不使用分配的内存时,一定要释放,否则容易出现内存泄露,溢出现象。
  使用案例,理解分配与释放内存:

#include<iostream>
using namespace std;
int main() {
	//分配内存
	int *pNum = new int;
	cout << "请任意输入数字:";
	cin >> *pNum;
	cout << "输入的数字为:" << *pNum << endl;
	cout << "数字存储地址为:" << pNum << endl;
	//释放内存
	delete pNum;
	return 0;
}

在这里插入图片描述

2.2 带关键字const的指针

  之前提到过关键const的的含义,被关键字const定义的变量,在程序中是不可修改的。指针是特殊的变量,所以const关键字同样适用指针,对于const的指针主要有三种:

  (1) 指针指向的数据为常量(使用了const关键字),不可修改,但是可以修改指针包含的地址(修改指针的值,或者理解为该指针不指向这个变量,去指向别的变量):

1.指针指向的数据为常量
int Num = 10;
const int *pNum = &Num;  //不能更改pNum指向的数据Num的值,即变量Num值无法修改

2. 想将Num改为20,错误的做法
*pNum = 20;  //错误

3. 正确的做法,修改指针指向,
int CopyNum = 20;
pNum = &CopyNum; //可改变指针指向的地址

  (2) 指针包含的地址为常量(使用了const关键字),可以修改指针指向数据的值,地址不可改:

int Num = 10;
int * const pNum = &Num; //不能更改pNum的值,即地址
*pNum=20;//可以修改

  (3) 指针包含的地址和数据都为常量(使用了const关键字),两者都不可修改。

int Num = 10;
const int * const pNum = &Num; 

3、指针和数组

  前面学过,声明一个数组:

int Array[10];

  此时,编译器将分配一个固定长为10的内存空间,同时提供一个指向数组第一个元素的指针,其实Array也是一个指针,指向数组第一个元素Array[0]

#include<iostream>
using namespace std;
int main()
{
	int Array[10]={0,1,2,3,4,5,6,7,8,9};
	int *pNum = Array;
	cout<<"*pNum = "<<*pNum<<endl;
	cout<<"Array[0] = "<<Array[0]<<endl; 
	return 0;
}

在这里插入图片描述

4、使用指针要注意的几个点

4.1 内存泄露

  前面讲了,使用new动态分配内存时,如果内存不在需要,就要用delete进行释放,否则会减少其他程序使用的内存空间,降低运行速度,也容易发生内存泄露

4.2 无效指针

  我们知道,利用*可以访问指针所指向变量的值,我们务必要保证指针指向的是有效内存但愿,否则容易使程序崩溃,就是无效指针。无效指向的原因有很多,比如之前所讲没有对指针进行初始化、使用new分配内存空间值过大等等。

5、总结

  以上是C++中,指针的一些基本知识,在这个基础上,可以再深入理解指针其他相关知识,例如多级指针等,大家可以把更多知识分享到评论区。
  最后,长话短说,大家看完就好好动手实践一下,切记不能三分钟热度、三天打鱼,两天晒网。大家也可以自己尝试写写博客,来记录大家平时学习的进度,可以和网上众多学者一起交流、探讨,我也会及时更新,来督促自己学习进度。一开始提及的博主【AI菌】,个人已关注,并订阅了相关专栏(对我有帮助的),希望大家觉得不错的可以点赞、关注、收藏

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cqy阳

预祝上岸,感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值