1、如何判断指针的类型
从语法的角度看,只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针 类型,这是指针本身所具有的类型
int *ptr; 指针的类型是int*
char *ptr; 指针的类型是char*
int **ptr; 指针的类型是int**
int (*ptr)[3] 指针的类型是int(*)[3]
int *(*ptr)[4] 指针的类型是int*(*)[4]
2、如何判断指针所指向的类型
当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当作什么来看待
从语法上看,只须把指针声明语句中的指针名字和左边的指针声明符“*”去掉,剩下的就是指针所指向的类型
int *ptr; 指着所指向的类型是int
char *ptr; 指着所指向的类型是char
int **ptr; 指着所指向的类型是int*
int (*ptr)[3]; 指着所指向的类型是int()[3]
int *(*ptr)[4]; 指着所指向的类型是int*()[4]
3、常量指针和指针常量
(1)、const char *p;
(2)、char *const p = a;
语句(1)定义了一个常量指针,即指向一个常量的指针,指向的内容是常量,不可修改,放在常量区的,但指针本身
可以修改,即“*p = b”,是非法的,*p是p指向的常量的第一个字符,是个常量,不能改变的。“p = &q”这是可以
的,指针可以指向不同的地址。
语句(2)定义了一个指针常量,即指针本身是个常量,不可修改,但指针指向的内容可以修改,一开始定义时让它指向
数组a,“*p = b”这是可以的,但“p = &b”是非法的
const常量*指针,当const在*之前就是常量指针,而const在*之后,就是指针常量。例如,“const char*p”即char*p
是个常量,所以内容是常量;“char* const p”即指针p是个常量。
常量指针指向的内容不可变,但地址可以改变,即指针可以指向别的地址;而指针常量是指指针本身不可变,而内容可以
修改。
注意:
(1)、如果指针常量指向的是字符指针变量,那么当修改*p时,原则上能够修改,在编译时能通过,但在运行时不能通过
因为试图企业修改常量区的内容,显然是非法的。
(2)、当指针常量指向另一个指针时,当这个指针指向别的内容时,那么指针常量还是指向原先的内容。
4、空指针的使用
(1)、用空指针终止对递归结构的间接引用,递归是指一个事物由这个事物本身来定义
(2)、用空指针进行函数调用失败是的返回值。许多C库函数的返回值是一个指针,在函数调用成功时,韩式返回一个指向
某一对象的指针;反之,则返回一个空指针
(3)、用空指针作警戒值。警戒值是标志事物结尾的一个特定值,例如,main()韩式的预定义参数argv时一个指针数组,
它的最后一个元素“argv[argv]”永远是一个空指针,因此,可以用下述方法快速地引用argv中的每一个元素。
5、函数指针与指针函数
(1)、函数指针:即指向这个函数的指针,定义为“数据类型(*fun)(参数列表);“,()的优先级比*高,所以*fun
加括号,如“void(*fun)(int*,int*);"
(2)、指针函数:即返回值是指针的函数,定义为“数据类型*fun(参数列表);”,如“char*fun(int*,int*);”
即返回值是char*型
6、通过函数指针调用函数的步骤
1、定义函数指针,如“int(*pfun)(int*,int*);”
2、定义函数,如“int fun(int*,int*);”
3、把函数的地址赋给函数指针,即pfun = fun
4、通过函数指针去调用这个函数“(pfun)(p,q);”,pfun是函数的地址,那么*pfun当然就是函数本身了
7、函数参数传递问题
在C语言中,有两种参数传递的方式,一种是值传递,另一种是指针传递。值传递很好理解,即把实参的值传递给
形参.而指针传递传的是地址,在C语言中,形参的值改变并不能改变实参的值,但形参所指向内容值的改变却能改变
实参。
8、NULL总是被定义为0吗
NULL不是被定义为0,就是被定义为“(void*)0”,这两种值几乎是相同的。当程序中需要一个指针时,一个纯粹的
0或者一个void指针都能自动被转换成所需要的任何类型的指针
9、NULL总是等于0吗
假如是指“与比较的结果为相等”,那么NULL确实总是等于0,这也就是空指针定义的本质所在
假如是指“其存储方式和整形值相同”,那么答案是不。NULL并不必须被存为一个整形值0,尽管这是NULL最常见的存储
方式,但在有些计算机中,NULL会被存成另外一些形式。
10、指针的值
指针的值也叫作指针所指向的内存区或地址。指针的值是指针本身存储的数值,这个值将被编译器当做一个地址,而不是
一个一把的数值