| |
指针:
(1) 什么是空指针,以及什么时候使用空指针: 有时,在程序中需要使用这样一种指针,它并不指向任何对象,这种指针被称为空指针。空指针的值是NULL
,NULL是在中定义的一个宏,它的值和任何有效指针的值都不同。NULL是一个纯粹的零,它可能会被强制转换成void*或char*类型。即NULL可能是0,0L或
(void*)0等。有些程序员,尤其是C++程序员,更喜欢用0来代替NULL。空指针有以下三种用法:
(1)用空指针终止对递归数据结构的间接引用。
(2)用空指针作函数调用失败时的返回值。
(3)用空指针作警戒值
(2) 什么是void指针,以及什么时候使用void指针: void指针一般被称为通用指针或泛指针,它是C关于“纯粹地址(raw address)”的一种约定。void指针指
向某个对象,但该对象不属于任何类型。当进行纯粹的内存操作时,或者传递一个指向未定类型的指针时,可以使用void指针。void指针也常常用作函数指针。
有些C代码只进行纯粹的内存操作。在较早版本的C中,这一点是通过字符指针(char *)实现的,但是这容易产生混淆,因为人们不容易判断一个字符指针究竟是
指向一个字符串,还是指向一个字符数组,或者仅仅是指向内存中的某个地址。
(3) 两个指针可以进行加减吗?两个指针可以进行减法:如果两个指针向同一个数组,它们就可以相减,其为结果为两个指针之间的元素数目。如果两个指针
不是指向一个数组,它们相减就没有意义。C本身无法防止非法的指针减法运算,即使其结果可能会给你的程序带来麻烦,C也不会给出任何提示或警告。指针相
减的结果是某种整类型的值,为此,ANSIC标准头文件中预定义了一个整类型ptrdiff_t。尽管在不同的编译程序中ptrdiff_t的类型可能各不相同(int或long或其
它),但它们都适当地定义了ptrdiff_t类型。两个指针是不能相加的。相加是没有意思的。
(4) NULL总是被定义为0吗? 在c中,#define NULL (void *)0 。当程序中需要一个指针时(尽管编译程序并不是总能指示什么时候需要一个指针),一个纯粹
的零或者一个void指针都能自动被转换成所需的任何类型的指针。在c++中 #define NULL 0 。
(5) 指针的复杂声明: int a[10]; /* 一个有10个元素的整型数组*/ int *a[10]; /* 一个有10个元素的数组,每个元素都是指向整数的指针*/ int (*a)
[10]; /* 一个指针,指向一个数组,该数组是一个有10个元素的整型数组*/ int *(*a)[10]; /* 一个指针,指向一个数组,该数组是一个有10个元素的数组,
每个元素都是指向整数的指针*/ int *(*a)(int); /* 一个指向函数的指针,该函数只有一个int型形参,该函数的返回值是一个指向整数的指针*/ int(*a
[10])(int); /* 一个数组,该数组含有10个元素,每个元素都是一个指向函数的指针,该函数只有一个ing型形参,该函数的返回值是一个指向整数的指针*/
const volatile int *a = (const volatile int *) 0xfff8; /* 一指向整数的指针,该指针的地址是0xfff8,其所指的内容是外部可变的,但对你的程序而言
却是只读的*/ typedef int (*(*(*fp)(void *))[10]) (int []); /* 定义fp为一个指针类型,指一个函数,其参数表是(void*),返回一个指向数组的指针,
数组有10个元素,元素类型是一个指针,指向一个函数,其参数列表为(int[]),返回值是int*/ fp * *(*(*a[10])(int))[10]; /*声明一个数组,包括10个元
素,每个元素是一个指针,指向一个函数,其参数列表为(int),返回值是指针,指向一个有10个元素的数组,元素类型是指针,指向另一个指针,这个指针指
向fp型。*/
(6) 怎样用指向函数的指针作函数的参数? 函数的指针可以作为一个参数传递给另外一个函数,这一点非常有意思。一个函数用函数指针作参数,意味着这个函
数的一部分工作需要通过函数指针调用另外的函数来完成,这被称为“回调(callback)”。处理图形用户接口的许多C库函数都用函数指针作参数,因为创建显示风
格的工作可以由这些函数本身完成,但确定显示内容的工作需要由应用程序完成。