Hello 今天分享的是我对C/C++指针方面的理解,好了废话少说我们进入正题。
我是这样看待指针的
C/C++的指针是被其它语言所诟病的,因为管理指针是一个很麻烦的事情。但是C/C++的优势体现也是在指针上,因为通过访问指针,程序可以直接操作内存,没错直接操作,只要你愿意按位都可以。
我是这样理解指针
在初学C++的时候,网上都说指针多么的难理解。但也许是我之前学过一点汇编,从而我感觉指针并没有传说中的那么难。在我眼里,内存就是一个bit一个bit的格子(你也可以认为是房子)。 当然这样的格子是非常非常的多的,于是便需要一系列连续的编号(门牌号)对其管理,而这个编号也就是内存中的地址。
当我们向系统申请内存时,系统会为我们开辟一段连续的空闲内存,并给我们这段内存中第一个格子的编号。 你也可以这样理解:当你需要住房时,调度员会给你房子的入口门牌号,而房子的多少取决于你需要多大的空间。
当我们对指针做加一减一的时候,指针会指向下一个或上一个内存块的第一个编号。而这里的内存块是由多个连续的bit格子组成,而组成这个块的bit格子的数量,是由指针的类型决定。
比如 char 是一个字节,而一个字节又是8个比特,而对于char类型的指针,每做加一的时候就是将指针向后移动8个bit格子。
二级指针
顾名思义二级指针便是指向指针的指针。也许对于初学者一时可能想不明白,那么让我为你细细道来。
当我们和系统获取内存时,系统会返回给我们指向该段内存首地址。而我们需要将该地址存储到一个变量中。如下:
int *ptr = new int;
在上面的代码中, 变量 ptr 中便是一个指针,存储了指向一段长度为4个字节(在32位操作系统下)的内存首地址。而对于二级指针便是指向 ptr 的指针。
int **secondptr = &ptr;
其实,上面代码中 int *ptr 也是一段内存,而这段内存为int类型的指针,在C/C++中所有指针的长度都为4个字节(64为操作系统为8个字节)。而二级指针便是指向ptr这段内存的首地址。
对于指针的操作,是操作内存中的数据,而对二级指针操作则是在操作指针(其实也是在操作内存中的数据,只不过数据是指针)。
哪里可以用的到指针
这里我向大家分享一下自己对内存的使用。如果你有更高的使用场景,欢迎在下面的评论区提出。
- *对于频繁而又大量的数据移动*:在实际开发中常常会遇到频繁的数据拷贝,而如果直接拷贝数据会降低程序的效率。而如果是指针拷贝,则永远都是移动4个字节(在64位系统是8字节)。
- *对于返回参数*: 当函数需要通过参数来返回数据时,我们可以使用指针(当然在C++中使用引用最好)。而当需要返回一个指针时,我们需要的是二级指针。
当然,这只是简单的使用,更多的技巧大家可以看下面推荐的书籍,这里就不赘述了。
关于指针的书籍推荐
在上一篇文章 如何快速学习 C/C++ 语法 中提到的 《C++ Prime》 一书便有对指针有讲解。不过在这里还有一本不错的书籍推荐给你 《C和指针》。 这本书籍详细的讲解了C指针的使用, 包括二级指针、函数指针以及使用指针的一些技巧。
我在使用指针中遇到的坑
内存越界
对于越界,其实就是访问了自己不该访问的内存,这样的行为后果是不可预期的。
而对于内存越界问题,只能在编程中对逻辑的把控。尤其是当使用循环操作内存时要尤为小心,要时刻注意所操作内存的长度,和每次操作的位置。
内存泄漏
我想内存泄漏对于程序员来说就是噩梦,至少对我来说是这样。内存泄漏就是我们获取了内存但却没有释放,我出现这样的错误主要是在异常退出的情况下忘记释放内存。 例如:函数中间发生异常而退出时… 循环中的break、continue;
至于避免方法,我只能说祝你好运了….
哈哈,开玩笑的。这里向你推荐一个Linux下检测内存泄漏的软件: VALGRIND 检查内存泄漏方法,这个软件可以检测出大部分的内存泄漏问题,期望能够帮助到你。
这里还有一个下下策献上:定时重启…(小编此时一脸坏笑)
最后
如果你发现任何问题或疑问,你可以在下面留言或者通过 微博 和邮箱联系我,我会第一时间给予答复。 本文出自 舍予书,如需转载请保留该段声明,非常感谢。