三分钟带你认识指针

c.png

指针可以说是程序员入门c语言最难懂最复杂的内容了,当时就是因为指针导致对c++失去信心,转行了前端,时隔四年再次学习c++,发现其实指针一点也不难, 只不过基础知识太少了,导致很难理解其中的含义,今天就来讲讲,重新学习后的收获。

1、内存

首先了解指针之前我们要先了解计算机的储存和运行原理
内存就是计算机运行时存储数据的地方,例如我们编程中的变量、常量等、都会存储在内存中。

image.png

上面这张图简单表示内存,所有的数据都是存放在这样一个一个的小格当中,每一个小格是一个比特(bit),八个小格就是一个字节,这个大家应该都听过,下面的单位换算应该在流量中都知道。
因为计算机只能识别二进制数据, 所以我们所有的数据最后都会转化成0/1(0或者1)这种形式的二进制数据存储在这样的格子当中,那么我们把这样一个小格单独拿出来看看。

//我们从代码的角度来看假设现在有一个变量a,并且赋值为2000
int a{ 2000 };
//那么编译时这个变量a就会存储在内存当中,我们假设为一个这样的小格,
//那么一个变量存储后就会有一个地址,和一个他本身的值,
//地址就像索引一样,标记他在哪个位置或者标识哪个是变量a,而值就是表示赋值的值

image.png

只需要知道每个变量或者常量存储在内存当中的形式就是这样,那么对我们接下来了解指针有着关键性作用

2、指针

1、基础认识

学习指针,那么就从代码进行讲解:

int a{ 1000 };    //定义一个变量a

int* ptr{ &a };   //定义一个指针ptr  指向的地址为a

image.png

来看这张图, 变量a创建后存储到内存会有一个地址和他的值,
指针ptr也有一个地址和他的值,两者是一样的, 但是指针不同的是,他的值存放的是其他人的地址,而不是一个具体的数,当我们指针ptr指向a时,那么ptr的值存储的就是a的地址,简单来说,指针存放的就是地址, 指向谁就存放谁的地址,就这么简单。

为了防止初学者看不懂我们来讲一讲代码

//c++语法


//定义变量
int a{ 1000 };  
//等同于
int a = 1000;
//等同于js
let a = 1000;
//定义指针
int* ptr{ &a };
//int* 用于定义指针
//ptr是一个变量    指针也分常量/变量  下面扩展来说
//&a是指向

2、指针的指针

既然我们已经了解了指针,其实指针的指针也是一个道理,我们不妨来一起看看:

int a{ 1000 };    //定义一个变量a

int* ptr{ &a };   //定义一个指针ptr  指向的地址为a

int** ptr2{ &ptr };//定义一个指针ptr2  指向指针ptr

image.png

就这么简单, 指针指向变量或者指向指针,都是存放的指向对象的地址。 我们来看看具体的代码,来确定这一结论

//c++语法




int a{ 1000 };    //定义一个变量a
int* ptr{ &a };   //定义一个指针ptr  指向的地址为a
std::cout <<"这是a的值:"<< a << std::endl;    //
std::cout <<"这是ptr的指向"<< ptr << std::endl;
std::cout <<"这是ptr指向的地址的值"<< *ptr << std::endl;

image.png
通过控制台打印结果来看, ptr表示的就是ptr的值,这里就是a的地址,因为这里的ptr指向的a,而a的值就是1000,
而*ptr也就是获取指向对象的值,这里就是获取a的值,

//c++语法




int a{ 1000 };
int b{ 2000 };
int* ptr{ &a };

ptr = 1000;  // ×   因为ptr存放的是地址,所以不能修改为具体的值
ptr = &b;     // √   可以通过改变指向来改变指针,这里指针指向b

std::cout << "现在ptr指向改为b,来看看ptr的值" << *ptr << std::endl;    

*ptr = 1000;// √   因为*ptr是获取指向对象的值, 所以可以进行修改,
//修改了值的话,指向的对象的值也会发生改变,也就是现在指向b的话, b也会被改变

std::cout << "现在给*ptr赋值,这里是*ptr的值" << *ptr << std::endl;
std::cout << "这里是b的值" << b << std::endl;
std::cout << "修改*ptr  b也跟着改变" << std::endl;
std::cout << "说明*ptr就代表b,他们指向同一个内存地址"  << std::endl;

image.png

如果这里看的不清楚可以自己敲一下代码,来看看指针和地址的变化,到这里就基本上对指针有了一个比较清晰的认识了, 我也是听到这里终于解开了我四年前未解开的谜题。
接下来讲一讲与本章有关但不是重点的点。

3、常量指针

前面说了指针也是一个变量, 只不过他值存放的是其他变量的地址,那么有变量当然也有常量。

常量指针其实还是有点难理解的, 这里的常量指针指的是不同通过*ptr的方式修改指向对象的值,而ptr本身还是个变量,先看代码,

int a{ 1000 };


int b{ 2000 };

const int* ptr{ &a };    //定义一个常量指针

//修改指针指向   
ptr = &b;       //可以
//修改指针对象的值    
*ptr = 5000;    //不可以
//说白了常量指针就是不可以通过指针修改指向对象的值

4、指针常量

看到这是不是已经开始烦躁了, 一个常量指针又来个指针常量,有完没完! 心里有一万只草泥马跑过…
其他结合二者来看就简单了, 常量指针是不可以通过指针修改指向对象的值, 那么指针常量就是不可以修改指针指向,二者相反就对了。

int a{ 1000 };


int b{ 2000 };

int* const ptr{ &a };    //定义一个指针常量
//这时候看这个ptr是不是就更像一个常量了,所以他的指向对象是不可以改变的,但是可以修改指向对象的值,

//修改指针指向   
ptr = &b;       //不可以
//修改指针对象的值    
*ptr = 5000;    //可以
//说白了常量指针就是不可以通过指针修改指向对象的值

5、指向常量的常量指针

好好好,这么搞是吧!
我当时看到这已经崩溃了,不过在了解了指针之后再看, 其实好像也没那么复杂, 就是记住他的作用就好了, 能看到这其实你已经理解了指针了。
其实不要被他这个称呼所迷惑了就好, 听这什么指向常量的常量指针, 听着就头疼, 但是其实他的本质就很简单,看代码吧

int a{ 1000 };


const int* const ptr{ &a }; 
//这个写法应该能猜到他是怎么回事儿了吧, 这不就是结合了常量指针和指针常量嘛
//既然是结合了两者,那只有一个结论, 两个不允许的他肯定都不允许
//也就是他不可能改变指向,也不可以改变指向对象的值 
//好, 一句带过, 就这么简单

3、总结

其实当时搞得我不想学c/c++的指针也没有那么难, 差的是一些基础知识, 了解了内存, 其实理解起来还是很轻松的, 当然还差一个举例子和我一样好的”sen se”啦!!!

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYi4iW5a' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片