第10章指针;指针是C语言中的一个重要的概念,也是C语言的一个重要特色。正确而灵活地运用它,可以有效地表示复杂的数据结构;能动态分配内存;能方便地使用字符串;有效而方便地使用数组;在调用函数时能得到多于1个的值;能直接处理内存地址等,这对设计系统软件是很必要的。掌握指针的应用,可以使程序简洁、紧凑、高效。每一个学习和使用C语言的人,都应当深入地学习和掌握指针。可以说,不掌握指针就是没有掌握C的精华。;指针的概念比较复杂,使用也比较灵活,因此初学时常会出错,务请在学习本章内容时十分小心,多思考、多比较、多上机,在实践中掌握它。我们在表达时也力图用通俗易懂的方法使读者易于理解。;10.1地址和指针的概念;型变量分配2个字节,对实型变量分配4个字节,对字符型变量分配1个字节。内存区的每一个字节有一个编号,这就是“地址〞,它相当于旅馆中的房间号。在地址所标志的内存单元中存放数据,这相当于旅馆中各个房间中居住旅客一样。请务必弄清楚一个内存单元的地址与内存单元的内容这两个概念的区别,如图10.1所示。假设程序已定义了3个整型变量i、j、k,编译时系统分配2000和2001两个字节给变量i,2002,2003字节给j,2004,2005给k。在程序中一般是通过变量名来对内存单元进行存取操作的。其实程序经过编译以后己经将变量名转换为变量的地址,对变量值的存取;都是通过地址进行的。例如,printf(“%D〞,i)的执行是这样的:根据变量名与地址的对应关系(这个对应关系是在编译时确定的),找到变量i的地址2000,然后从由2000开始的两个字节中取出数据(即变量的值3),把它输出。输入时如果用scanf(%D,i),在执行时,就把从键盘输入的值送到地址为2000开始的整型存储单元中。如果有语句“k=i+j〞,那么从2000、2001字节取出i的值(3),再从2002、2003字节取出j的值(6),将它们相加后再将其和(9)送到k所占用的2004、2005字节单元中。这种按变量地址存取变量值的方式称为“直接访问〞方式。;还可以采用另一种称之为“间接访问〞的方式,将变量i的地址存放在另一个变量中。按C语言的规定,可以在程序中定义整型变量、实型变量、字符变量等,也可以定义这样一种特殊的变量,它是存放地址的。假设我们定义了一个变量i-pointer,用来存放整型变量的地址,它被分配为3010、3011字节。可以通过下面语句将i的刂?2000)存放到i-pointer中。
i-pointer=i;
这时,i-pointer的值就是2000,即变量i所占用单元的起始地址。要存取变量i的值,也可以采用间接方式:先找到存放“i的地址〞的变量,从中取出i的地址(2000),然后到2000、2001字节取出i的值(3)。;打个比方,为了开一个A抽屉,有两种方法,一种是将A钥匙带在身上,需要时直接找出该钥匙翻开抽屉,取出所需的东西。另一种方法是:为平安起见,将该A钥匙放到另一抽屉B中锁起来。如果需要翻开A抽屉,就需要先找出B钥匙,翻开B抽屉,取出A钥匙,再翻开A抽屉,取出A抽屉中之物,这就是“间接访问〞。图10.2是直接访问和间接访问的示意图。;图10.2
;为了表示将数值3送到变量中,可以有两种表达方法:
(1)将3送到变量i所标志的单元中。见图10.2上。
(2)将3送到变量i-pointer所“指向〞的单元(即i所标志的单元)中。见图10.2下。
所谓“指向〞就是通过地址来表达的。i-pointer中的值为2000,它是变量i的地址,这样就在i-pointer和变量i之间建立起一种联系,即通过i-pointer能知道i的地址,从而找到变量i的内存单元。图10.2中以箭头表示这种“指向〞关系。
由于通过地址能找到所需的变量单元,我们可以说,地址“指向〞该变量单元(如同说,房间号“指向“某一房间一样)。因此在C语言中,将地址形象化地称为;“指针〞。意思是通过它能找到以它为地址的内存单元(例如根据地址2000就能找到变量i的存储单元,从而读取其中的值)。一个变量的地址称为该变量的“指针〞。例如,地址2000是变量i的指针。如果有一个变量专门用来存放另一变量的地址(即指针),那么它称为“指针变量〞。上述的i-pointer就是一个指针变量。指针变量的值(即指针变量中存放的值)是指针(地址)。请区分“指针〞和“指针变量〞这两个概念。例如,可以说变量i的指针是2000,而不能说i的指针变量是2000。;10.2变量的指针和指向变量的指针变量
如前所述,变量的指针就是变量的地址。存放变量地址的变量是指针变量,用来指向另一个变量。为了表示指针变量和它所指向的变量之间的联系,在程序中用“*〞符号表示“指向〞,例如,i-pointer代表指