指针
1、未初始化和非法的指针
一个极为常见的错误:
int *a;
*a = 12;
warning: 声明一个指针,但未初始化,那么12存储在什么位置就未可知。
声明一个指针,不会创建用于存储的内存空间。对于未初始化的指针,执行间接的访问操作是非法的。
如果a的初始值是个非法地址,赋值语句将会出错,从而终止程序;
如果a是一个合法地址,a指向的位置上的值将被修改,虽然你并无意去修改它。像这种类型的错误难以捕捉。切记对指针进行间接访问前,确保已经被初始化。
对NULL指针解引用是非法的,因为NULL指针并不指向什么值。
2、指针常量
*100 = 25; //非法操作,因为解引用只能用于指针类型表达式。
*(int *)100 = 25; //把100从 整型 转换为 指向整型的指针,这样的间接访问是合法的。主要用于访问硬件本身。
3、指针的指针
int **c; //表示表达式**c的类型是int。
4、指针表达式
指针表达式作为 右值 就是表达式的值, 左值 是表达式的值对应的地址。
可否为左值 需要看该地址是否 可知。
++和--操作得到的是原值的一份拷贝,意思是:值是确定的,值所在的内存位置是不确定的。
*和++采用右结合顺序,优先级相同
5、指针运算
5.1、指针 +- 整数
当且仅当指针 指向 数组时
指针和整数进行算术运算时,整数在执行加法运算前始终会根据合适的大小进行调整。
合适的大小:指针所指向类型的大小,“调整”就是:整数值 * 合适的大小。
5.2、 指针 - 指针
当且仅当两个指针都指向 同一个数组中的元素 时 才允许。
for( vp = &value[N_VALUES]; vp > &values[0]; vp--) *vp = 0;
在数组第1个元素被清除后,vp的值还减去1,vp移到了数组边界外。标准只允许在指向数组元素的指针在数组内部进行比较。这种写法在有些C编译器中将报错。
worning:
指针运算只有作用于数组中其结果才是可以预测的。对任何非指向数组元素的指针执行算术运算是非法的(比如:链表操作)。
如果指针减去一个整数后,运算结果产生的指针指向数组第一个元素之前,非法;
加法不同,如果结果指针指向数组最后一个元素后面的那个内存位置仍是合法(但不能对这个指针执行间接访问操作),再往后就不合法了。
任何两个指针间可以用进行 相等 或 不相等 的比较。
如果两个指针指向同一个数组中的元素,那么他们之间还可以执行 < 、<= 、 >=等关系运算。
指针解引用前 必须 先初始化。