什么是指针?
其实指针看起来复杂,听起来复杂,学起来复杂,但是总结下来指针到底是个啥,也就一句话。
指针(Pointer)就是内存的地址,C语言允许用一个变量来存放指针,这种变量称为指针变量。指针变量可以存放基本类型数据的地址,也可以存放数组、函数以及其他指针变量的地址。
程序在运行过程中需要的是数据和指令的地址,变量名、函数名、字符串名和数组名在本质上是一样的,它们都是地址的助记符:在编写代码的过程中,我们认为变量名表示的是数据本身,而函数名、字符串名和数组名表示的是代码块或数据块的首地址;程序被编译和链接后,这些名字都会消失,取而代之的是它们对应的地址。
1) 指针变量可以进行加减运算,例如p++、p+i、p-=i。指针变量的加减运算并不是简单的加上或减去一个整数,而是跟指针指向的数据类型有关。
2) 给指针变量赋值时,要将一份数据的地址赋给它,不能直接赋给一个整数,例如int *p = 1000;是没有意义的,使用过程中一般会导致程序崩溃。
3) 使用指针变量之前一定要初始化,否则就不能确定指针指向哪里,如果它指向的内存没有使用权限,程序就崩溃了。对于暂时没有指向的指针,建议赋值NULL。
4) 两个指针变量可以相减。如果两个指针变量指向同一个数组中的某个元素,那么相减的结果就是两个指针之间相差的元素个数。
5) 数组也是有类型的,数组名的本意是表示一组类型相同的数据。在定义数组时,或者和 sizeof、& 运算符一起使用时数组名才表示整个数组,表达式中的数组名会被转换为一个指向数组的指针。
为什么要学习指针?
有同学就要说了,既然指针这么难,这么不通俗易懂,为什么要学习他呢?其他高级语言都是把这块基本屏蔽掉了,不在让程序员直接操作指针,这里不直接操作指的是不让程序员用指针进行运算和强转而不是彻底没有了。举个java的例子
Objectobj=newObject();Objectsec=obj;sec=newObject();
如果你去仔细研究他们的行为,就会发现 obj, sec 都只是一个指向对象的东西,可以为空,也可以修改指向,所以它们其实都是指针,只是 Java 的教材里面不在去提这东西而已,具体原因看我后面讲解便知道了。
继续说为什么学习指针,为什么学习指针就必须要说到指针的优点了。
a、指针可以直接操作变量地址,所以很灵活。
b、指针操作会减少很多变量的拷贝使得程序性能提升。
c、可以动态分配内存。
这些优点使得很多后台性能要求很高的系统、游戏内核、一些高并发的中间件都是使用C&C++语言开发出来的。比如强大的linux系统、nginx,mysql、redis等等。
曾经看到一个搞笑的评论:道生一,一生二,二生三,三生万物;电脑生汇编,汇编生C , C生C++,C/C++生万物。
为什么说指针是 C 语言的精髓
如果 C 语言没有指针,一切都通过值传递,参数将永远只有输入参数,所有的结构体只要参与运算都具有极高的开销,因为每传递进函数参数一次就必须全体复制一次。
另外一点:C语言无法在参数中传递数组,一切数组在函数参数传递时退化为指针,因此如果没有指针,数组将无法通过函数参数传递。
还有一点,在C语言中函数是一个指针,如果没有指针,就无法定义C语言函数,无法使用和调用C语言函数,更无法将函数作为一个变量传递。——换句话说,没有指针,C语言将没有函数,一个没有函数的语言会是什么概念?
实际上指针这概念在绝大多数高级语言中都普遍运用了,只是人家不叫指针,通常叫做引用而已。例如 Java 的所有对象变量从 C 语言的角度都实际上保存的是一个指针而不是对象本身。
完全的舍弃指针,C程序将变得低效难懂,因为你无法让在任何子函数中修改一个结构体的内容。这种程序类似于无状态程序。
或许在C的观念里,指针不是什么精髓,它只是一扇门,推开门,后面是整个世界。这是C最独特的优势,也是这门诞生于上世纪七十年代早期的、老掉牙的语言,至今仍能雄霸最流行语言排行榜之首的……幕后“黑手”。