如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
一、指针(pointer):(一)描述:指针被存放在内存中,它的值是它指向的内存单元的地址。要足够保存这个地址,它的大小自然不会小于该机器的字长(准确来说,这也和编译器的实现有关:若在32位平台上使用16位的TC,则地址和指针仍是16位的)。它提供了一种通过*运算符(dereference,解引用)来访问内存单元的方式。(二)定义和声明:一般来说,指针的声明就是它的定义(对于变量和常量来说,声明一般都是它的定义。据我所知,只有在声明时使用extern且未在该处初始化,或在类类型的定义中声明类静态数据成员时例外。本文将要描述的其他3者也相同,下文就不再重复这句了)。作为一个良好的编程风格,指针应被初始化为一个实体的地址或NULL,使用如下格式定义(关于&和*运算符的描述可以见下文):关于NULL,VC++6.0中的某些C标准头文件有如下定义(如<stdlib.h>和<stdio.h>。再次注意:未特别指明时,下文的实现均指在VC++6.0中):而C++标准头<cstdlib>和<cstdio>只是简单地分别#include了<stdlib.h>和<stdio.h>,并包含在namespacestd中。其他的C++标准头(至少所有和输入输出相关的都是如此)通过几层include,最终也包含了<stdio.h>或<stdlib.h>。另外,指针还可以指向一个函数,这被称为函数指针。使用如下方式声明一个函数指针:顺便提一下,使用如下方式定义一个指针常量(即该指针的内容为常量,也即该指针一般不能再指向其他的地址):将定义的左边改为type*constpointer即可。注意const修饰的是它左边的类型(这里我将指针也当成类型),当它左边没有类型时,才会修饰右边的类型。关于这点,volatile和const是一致的。下面做个简单的测试,看看指针究竟是什么:输出:(这是在我同学的电脑上得到的结果,也许和你的不同。下面不再注明)&b=0012FF7Cp1=0012FF7C&p1=0012FF78p2=0012FF7C&p2=0012FF74pn=00000000&pn=0012FF70反汇编可得到如下代码(只提供关键部分,下同):由上述测试得知,指针的内容就是地址。注:1.对汇编不太了解的,也应该可以从测试的输出得出上述结论。反汇编只是为了解释指针的存储原理。2.由于new返回的是一个指针,所以实际和第9句是类似的,就不再做重复的实验了。(三)运算:对一个实体的地址使用*运算符,可以得到该实体的地址对应的内存单元的值(概念上来说可被视为一个引用,一般为该实体本身,可以作为左值(即可以通过名称或地址(而非靠纯粹的计算)来访问的表达式))。这个值的类型与*的操作数类型相同。对一个非void类型的指针使用*运算符,可以得到该指针指向的内存单元的值(引用)。这个值的类型与该指针的类型相同。注意,若该内存单元是不可读的,则程序会崩溃;若该内存单元是不可写的,却对其赋值,则程序也会崩溃。对一个实体使用&运算符,可以得到它的地址。这个实体是一个左值,且不能为位域成员。这个地址是一个右值,它不能被赋值或再次使用&运算符。对一个非const类型指针使用=运算符,并提供一个地址或指针作为右操作数,可以使该指针的值更改为这个地址或指针的值。这里的注意事项同指针的定义和声明。对一个非const或void类型指针使用++或--运算符,可以让该指针的值增加或减少(sizeof(指针的类型))(我用西文字符的括号表示一个表达式,下同),一般来说会指向下一个或上一个实体(如果指针未越界的话,下同)。对一个非const或void类型指针使用+或-运算符,并提供一个ptrdiff_t类型的参数(ptrdiff)(可以为负数)作为操作数,可以得到一个该类型的指针。这个指针是一个右值,它的值为((指针的内容)op((ptrdiff)*sizeof(指针的类型))),op为使用的运算符。一般来说会指向与原实体相距ptrdiff个实体。对一个非const或void类型指针使用+=或-=运算符,并提供一个ptrdiff_t类型的参数(ptrdiff)作为右操作数,可以让该指针的值增加或减少((ptrdiff)*sizeof(指针的类型)),并且结果可以作为左值。一般来说会指向与原实体相距ptrdiff个实体。对两个同类型或有派生关系的非void指针使用-运算符,可以得到一个类型为ptrdiff_t的值。这个值即(它们的差值)。对两个同类型或有派生关系的非void指针使用比较运算符,可以得到一个bool值。比较的方法是拿它们的内容进行比较,