许多面试官常说:C程序员新手和老手的一大差别就在于是否对指针有深刻理解,能否高效利用指针。
笔者在此建立《深入理解C指针系列》专栏与大家分享我的C指针学习。
- C语言编程的精髓就是对指针的精巧使用,利用指针变量可以表示各种类型的数据结构,并能想汇编语言一样处理内存地址,
可以编出精炼而高效的程序。指针极大的丰富了C语言的功能。
指针变量的大小
指针变量的值就是某个内存单元的地址。
指针的大小在32位机器上是4个字节,在64位机器上是8个字节。
指针的类型
指针的类型有int,char,float,double等。指针的类型决定了指针向前或向后走一步的长度。
p1和p2指针走一步的位置会如何呢?
p1是char指针,每次访问1个字节。
p2是int 指针,每次访问4个字节。
空指针
*int p=NULL; 表示指针指向0地址处的空间。
NULL宏是强制类型转换为void指针的整数常量0.在<stdio.h>中定义为:
我们定义指针是,经常将指针用NULL初始化。
值得注意的是:用户无法对0地址空间(NULL)直接解引用。否则,就会引起程序崩溃。尤其在函数传参时经常会忽略这一问题。
在《剑指offer》中有这样一段代码:
int StrToInt(char* string)
{
int number = 0;
while (*string != 0)
{
number = number * 10 + *string - '0';
++string;
}
return number;
}
面试官不能容忍的错误就是程序不能鲁棒。以前面的代码为例,只要输入一个空指针,程序立即崩溃。这样的代码如果加入软件当中,那么将是灾难。因此,当面试官看的代码中对空指针没有判断并加以处理的时候,通常连往下看的兴趣都没有。
防止空指针被解引用
我们在函数的开头判断一下空指针即可。通常采用包含着**<assert.h>** 中的 assert函数,assert(p);
如果string不为空指针,这什么事都不会发生。
相反,string为空指针是,会报错。
指针变量与整数的加减运算
p+n;表示指针走n步。
整形变量p+1表示的是在内存中与p相邻的下一个整形变量的地址。
指针的比较,相减
p1<p2表示p2的地址大于p1的地址
指针相减的结果表示指针的步长。
野指针
野指针是指指针指向的未知内存。
产生原因主要有:
- 指针未初始化。
- 指针越界访问
- 指针指向的空间被释放
如何规避野指针?
- 指针初始化
- 小心指针越界
- 指针指向的空间被释放后,指针指向NULL
- 指针使用时检查有效性。
标准规定
C语言标准规定:允许指向数组元素的指针和指向数组最后一个元素后面的那个内存位置的指针进行比较,但是不允许与指向第一个元素之前的那个内存地址进行比较。
具体这个标准是什么意思,举例说明:
分别用方法1和方法2 初始化数组arr[5]。看似两种方法都能达到目的。
由于C语言的规定:方法1比方法2好。方法2要避免使用。
方法1中,指针vp从指向数组最后一个元素后面arr[5]的地址处一直递减到数组的首元素地址处。
方法2中,指针vp从指向数组最后一个元素的地址处递减到首元素前面arr[-1]的地址处,并进行了指针的比较。这是标准不允许的。