首创性并非首次观察某种新事物,而是把旧的、很早就是已知的,或者是人人都视而不见的事物当新事物观察,这才证实是有真正的首创头脑 —尼采java
<p align="center">本文已经收录至个人GitHub,欢迎你们踊跃star 和 issues。</p>
<h3 align="center"><a href="https://github.com/midou-tech/articles" target="_blank">https://github.com/midou-tech/articles</a></h3>;
<h4 style="color:red;text-align:center">点关注,不迷路!!! </h4>mysql
指针是C语言学习者绕不过的一道坎,也是C语言学习者不得绕过的一道坎。辨别一我的C语言学的好赖就看他对指针的理解怎么样。指针内容也是工做面试常常问到的问题。本文将带你从新认识那个绊倒你的指针,以解你们的心头之惑(恨)。linux
有同窗就要说了,既然指针这么难,这么不通俗易懂,为何要学习他呢?其余高级语言都是把这块基本屏蔽掉了,不在让程序员直接操做指针,这里不直接操做指的是不让程序员用指针进行运算和强转而不是完全没有了。举个java的例子nginx
Object obj= new Object(); Object sec= obj; sec = new Object();
若是你去仔细研究他们的行为,就会发现 obj, sec 都只是一个指向对象的东西,能够为空,也能够修改指向,因此它们其实都是指针,只是 Java 的教材里面不在去提这东西而已,具体缘由看我后面讲解便知道了。git
继续说为何学习指针,为何学习指针就必需要说到指针的优势了。程序员
这些优势使得不少后台性能要求很高的系统、游戏内核、一些高并发的中间件都是使用C&C++语言开发出来的。好比强大的linux系统、nginx,mysql、redis等等。github
曾经看到一个搞笑的评论,hhh面试
道生一,一辈子二,二生三,三生万物redis
电脑生汇编,汇编生C , C生C++,C/C++生万物sql
其实指针看起来复杂,听起来复杂,学起来复杂,可是总结下来指针究竟是个啥,也就一句话。
<p ><h4 style="color:red;text-align:center">指针就是地址,指针变量就是一个存放内存地址的变量</h4></p>
<img src="https://i01piccdn.sogoucdn.com/db3bc129d2c88816"></img>;
你没看看错,是的就是这么简单明了。一般咱们说的指针就约等于说的是指针变量。
不少人不明白指针其实也就是不明白内存地址,因此要想明白指针必须先明白指针和内存之间的关系。在讲内存和指针之间的关系以前先说下什么是内存。
先明白一个问题,什么是内存?编程人员常说的内存指的是什么?
内存是电脑的一个硬件组成部分。从单片机的组成咱们能够看到,CPU、内存和输入输出接口,就组成一个完整的电脑,其余通通属于外设。内存是能够被CPU经过总线进行操做的,也就是与CPU之间有总线相链接的。电脑全部的输入输出,都是要从内存来实现的。内存包括只读内存ROM和读写内存RAM,但在我的电脑(PC)中,咱们一般所说的内存,是指读写内存。
程序人员常说的内存实际上是虚拟内存,程序直接操做的是虚拟内存而不是真正的物理内存。
纳尼 程序都是操做的虚拟内存? 那虚拟内存是个啥东西?
这里先给你们画张C语言程序的内存布局图。关于进程和内存管理会在后面的文章讲出来,记得微信搜索 龙跃十二 点关注。
这个图很好的描述了内存地址的布局,指针变量里面存放的地址也就是这个内存地址。顺便说下啥是内存地址,用十六进制表示出来的一串数字编号(就比如你家的门牌号),只是这个数字是给内存标号的。32位系统下这个编号是4byte(32个bit)表示的,64位系统下是8byte(64bit)表示的。(这个小问题面试会被问到的)
int *p; char *p1; float *p2;
声明仍是很简单,指针的类型 * 变量名便可声明一个指针变量。
int num = 5; int *p = #
此时就是一个int类型的指针变量指向一个int变量,画个图解释下。
以很清楚的看到指针p存放着变量num的地址,咱们一般说指针p指向变量num,当p知道变量num以后,p就能够对变量num为非做歹了,好比
int main(){ int num = 5; int *p = # printf("*p=%d,num=%d\n",*p,num); //此时num的值就变为5 p+=1; printf("*p=%d\n",*p); //此时p指向了哪里?这句代码会不会报错? }
从上面的声明实例能够看到我定义了三种类型的指针,能够看出指针是有类型的。这里有同窗就有疑问了,不是存放内存地址的么,内存地址不就是一串十六进制表示的数字么(其实底层都是二进制),哪来的什么类型一说呢,为何又须要类型呢?
这个疑问很好,我当时学习的时候也是很疑惑。首先咱们明白了指针是一个存放地址的变量,明白这点还不够还必须理解另一个问题就是
字节(Byte)是用于计量存储容量的一种单位,每个字节由8位组成(1Byte = 8bit)。地址能够理解为在一片内存中,每一个字节(Byte)的编号。
因此不少人确定会明白了,指针存放的是一个变量的首个字节的地址,那么问题来了。
int a = 5; int *p = &a;
咱们声明指针p指向变量a的地址,也就是说指针p里面存放着变量a的首地址,在32位平台下,int a 是4字节,指针去取a的值的时候找到的是a的首地址,那怎么拿到变量a,聪明的同窗已经恍然大悟,是的,没错,因此咱们的指针须要类型的,编译器去取指针指向的内容时候会根据指针的类型去取。画个图以下
此刻我相信你对指针已经有了很高的理解了。指针的大小很好理解 就是存放地址的范围,地址的范围是操做系统地址线的根数决定,因此指针的大小是随操做系统的寻址范围决定的,通常32位系统地址总线也是32根,寻址范围是2^32次方
顺便说下32位操做系统和64位操做系统的区别在哪里,系统的位数表明运算能力,所谓32位就是能计算的字长是32位的,64位系统能计算的字长是64位。处理器的字长越大,说明它的运算能力越强。
<h5 align="center">点赞