(在整理笔记的时候同时加上了本人的见解,也用了自己的语言去描述某些难理解的地方,如有BUG,欢迎纠正)
指针变量
什么是指针变量
在32位的平台下,最大内存为4G,这些内存被分为n个字节,而每个字节都对应着唯一的整数编号,这个整数编号称为地址,4G大小的内存,编号从0到4G-1。同时地址也称为指针。
指针变量就是用来记录地址数据,如果一个指针变量中记录了一个存储区的地址则可以使用这个指针变量找到那个存储区。
指针的类型
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。
指针变量也分类型,不同类型的指针适合与不同存储区捆绑。
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。
让我们看看以下例子中各个指针的类型和指针所指向的类型:
(1)int *p_num; //指针的类型是int *,指的类型是int
(2)char *p_c; //指针的类型是char *,指的类型是char
(3)int **pp_num; //指针的类型是 int **,指的类型是int *,是一个2级指针
(4)int (*p)[3]; //指针的类型是 int(*)[3],指向的类型是int[],指向一个整型数组 的指针
(5)int *(*p_arr)[4]; //指针的类型是 int *(*)[4],指向的类型是int*[],指向一个 指针数组的指针
(6)int (*func)(void);//指针的类型是int (*)();指向的是int(),指向一个函数的指针
在上述例子中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。
当我们声明一个指针变量的时候,如果没有给指针捆绑一个存储区,那指针会随机捆绑一个存储区,这样的做法很危险,会带来不可预料的后果。所以声明一个指针变量的时候必须给指针变量捆绑一个存储区,或者让它成为一个空指针(空指针里面记录记录空地址(NULL),这个地址数值就是0)。
指针的值
指针的值,或者叫指针所存储的内存地址编号。
指针的值是指针本身存储的值,这个值将被编译器当作一个地址,而不是一个一般的值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。
指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。
指针所指向的内存区和指针所指向的类型是两个完全不同的概念。
指针本身所占据的内存区
指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在32位平台里,指针本身占据了4个字节的长度。
指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。
指针的算术运算
地址数据可以进行如下计算
地址 + 整数 地址 - 整数 地址 - 地址
地址数据加减整数n事实上加减的是n个捆绑地址的数据类型的大小。地址之间做减法结果是一个整数,这个整数代表两个地址之间包含的捆绑存储区个数。
由于时间问题,指针使用,指针的详解笔记,过2天再整理。