E-mail:
C语言的焦点总是落脚在指针上,因为C语言的强大和灵活集中体现在其丰富的指针使用方法。在C程序中使用指针是一件轻松愉快的事情。因为指针作为一种数据类型,这一抽象概念符合了我们的思维习惯,而且它执行效率高、节约内存,所以指针成为了几乎所有C程序员的最爱。 不过,指针好比一把双刃剑,准确的使用,会让我们爱不释手;反之,不熟练的使用者可能会因为它而绞尽脑汁,惹来三千烦恼丝;或者说,它可能让你尝尽愁滋味,甚至于“抽刀断水水更流,举杯销愁愁更愁”!
为此,我尝试着对C语言中指针使用做一个详尽的总结。
1.
指针本质上是一种变量,一种特殊的变量,它的特殊之处在于:它里面存储的数值被解释成为内存里的一个地址,而一般的变量包含的实际是真实的数据。
指针在编译器和操作系统的眼里,是一个无符号整数(Unsigened int),一个以当前系统寻址范围为取值范围的整数。32位系统下地址空间是4G-byte(0 ~ 2^32-1)二进制表示长度为32bit,即4B,它需要占用四个字节的存储空间。所以用sizeof(void*)获得的值为4。 此时指针相当于一个指示器,它告诉程序在内存的哪块区域可以找到数据。
指针是一个非常重要的概念,有很多程序和算法都是围绕指针设计的,如链表、遍历等。
2. 指针的定义
指针具有四个属性:指针的类型、指针所指向的类型、指针的值(指针所指向的内存区)、指针所占据的内存区
int *pNa; //定义了int类型的指针 pNa;
一般程序员给指针变量取名时,以p为首字符,表示这是一个指针,便于代码阅读和理解。 需要注意的一点是,尽管 int* pNa; 和 int *pNa; 等效,但是专业的程序员偏向于使用后一种编码风格,因为 int *pNa, *pNb; 定义了两个指针; 反之, int* pNa, pNb; 则是一种相当糟糕的定义(pNb不是指针,但是看上去却不然)。
3. 指针赋值 及转换
同类型直接赋值,一类型需要进行转换;
强制类型转换: 可以把表达式结果硬性转换为指定类型;
4.指针声明 (用编译器的眼光看待)
指针具有四个属性:指针的类型、指针所指向的类型、指针的值(指针所指向的内存区)、指针所占据的内存区
【例1】指针声明的例子
(1)int*ptr;
(2)char*ptr;
(3)int**ptr;
(4)int(*ptr)[3];
(5)int*(*ptr)[4];
指针的类型 从语法角度看,将指针声明语句中的指针名称去掉,剩下的部分就是这个指针的类型。【例1】中各个指针的类型:
(1)int*ptr; //指针的类型是int*
(2)char*ptr; //指针的类型是char*
(3)int**ptr; //指针的类型是int**
(4)int(*ptr)[3]; //指针的类型是int(*)[3]
(5)int*(*ptr)[4]; //指针的类型是int*(*)[4]
指针所指向的类型 从语法角度看,将指针声明语句中指针名称和名称左边的指针声明符*去掉,剩下的就是指针所指向德类型。 当程序代码通过指针访问指针所指向的内存区时,指针所指向的类型告知编译器改把那篇内存区里的内容当做什么来看待。因此,在指针的算术运算中,指针所指向的类型有很大的作用。【例1】中各个指针所指向的类型:
(1)int*ptr; //指针所指向的类型是int
(2)char*ptr; //指针所指向的的类型是char
(3)int**ptr; //指针所指向的的类型是int*
(4)int(*ptr)[3]; //指针所指向的的类型是int()[3]
(5)int*(*ptr)[4]; //指针所指向的的类型是int*()[4]
指针的值 或者 指针所指向的内存区 地址
指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。 指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为 sizeof(指针所指向的类型) 的一片内存区。一般,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。
(仍在修改编辑中)
参考:
阅读(906) | 评论(0) | 转发(0) |