李柯景,鲁光男
(长春大学 计算机科学技术学院,长春 130022)
经过多年承担C语言程序设计这门课的教学任务,笔者发现学生在初学指针的时候,理解和掌握关于指针的基本概念并不是很难,但往往在学完指针的基本使用方法之后还是不能够深刻理解指针在C语言中的重要作用。因此,笔者对C语言使用指针的必要性做简要的总结,便于学生更好的掌握和理解指针的概念,灵活的应用指针。
在C语言程序设计中,我们可以通过变量的指针(即变量的内存地址)来引用内存单元的值,这种方式称为间接访问。对于数组,采用指针变量自增运算引用数组元素要比利用数组名称直接访问的方式执行效率高。
比如:
程序段1(利用数组下标变化访问):
程序段2(利用指针间接访问)
以上两个程序段完成的功能都是一样的,都是让数组s中的所有元素的值均为0。程序段1中,每寻址一个数组元素都要进行地址的算术运算,即a[i]=*(a+i)。要通过数组名加上偏移量来实现对每个数组元素的访问。而程序段2只需要通过指针的自增运算来实现对数组元素的访问。由于自增运算的执行效率较高,因此程序段2的执行效率要比程序段1的高。
C语言中利用字符数组存放字符串,可以方便地使用指向字符的指针变量操作字符串。通过指针的移动来实现对不同位置字符的访问。如果是多个字符串还可以通过字符型指针数组来实现对多个字符串的灵活处理。如程序1:
对于"Melissa","Bob","Tom","Peter"这四个长度不等的字符串,可以采用字符数组进行存放。由于二维数组的列数是相等的,若采用二维数组进行存放则比较浪费存储空间。采用字符数组则可以解决这个问题。可以通过循环,利用指针数组元素下标的变化来实现对不同字符串的访问,大大提高了程序的效率。
每个指针数组元素对应一个字符串,倘若相对多个字符串求最大值或者进行排序操作,只需要通过改变指针数组中个元素的指向,就可以实现,节约了大量移动数据的步骤,程序的效率得到提高。
函数指针为指向函数的指针[4]。函数在内存中占据连续的一片存储单元,而函数名就是这片存储单元的首地址。可以通过对指向函数的指针变量的访问来完成对函数的调用。如程序2所示:
程序2中,定义了一个指向函数的指针数组,数组中的两个元素分别指向函数sqrt和fabs。因此当键盘上输入数据data后,根据用户的选择就可以实现对所输入的数据进行开平方或者求绝对值的操作。对这两个函数的调用,是通过访问指针数组元素来实现的。
倘若程序中所需要调用的函数不仅仅有两个,而是更多。那么就需要用多个的if语句或swich结构去判断哪个函数被调用哪个不被调用。那就需要大量的代码。若采用指向函数的指针数组来完成则可以省略大量的代码书写。通过指针数组下标的变化实现对不同函数的调用,省去了大量编写代码的工作量,代码的执行效率也得到提高。
通过以上的介绍,灵活的使用指针,可以使某些程序的效率得到提高。此外,当函数间参数传递时,尤其是大量数据的参数(例如结构体变量等),将它们地的址作为参数传给函数,这样可以省去编译器为它们制作副本所带来的空间和时间上的开销,从而提高了程序的效率。由此可见,灵活的使用指针进行编程,在提高程序效率方面起着重要的作用。
当普通变量作函数参数时,只能通过return语句得到一个返回值,若被调函数中没有返回值,则无论形参如何变化,主调函数中的值是不会发生改变的。如程序3所示:
程序3:
在swap函数中实现了变量p和q的交换,但程序的输出结果仍然为a=3,b=4。若将程序修改为指针变量作为函数参数如程序4所示:
程序4:
该程序的运行结果为:a=4,b=3。实现了a与b的真正交换。由此可见,使用指针变量作为函数的参数,可以得到多个变化的值。而不是只能得到一个返回值。
指针为C语言的动态内存分配系统提供支持。
例如:统计本班学生C语言程序设计这门课的总分和平均分。可以利用数组来进行编程。由于数组的大小要在定义时确定,不能够在程序运行时动态分配,因此必须事先确定数组的大小,即班级的人数。假如班级有35名学生,就需要根据分数的数据类型来分配连续的一片存储单元来存放相应的分数。假如程序要修改为对全年级350人进行统计,这期间还有其他原因造成参加考试人员的增减。那么预先分配的数组大小就要发生改变。倘若个数以最大计则造成了存储空间的浪费,分配太小则又无法临时改变数组的大小。此时,我们可以利用指针来实现对内存的临时分配。
在C语言中可以利用动态分配函数malloc()或calloc()为指针变量分配内存,建立动态数组。例如:int*p;
表示向系统申请5个连续的整型数相应大小的存储空间,p指向了这段存储空间的首地址。
又如:float*q;
表示向系统申请5个连续的的float类型的存储单元,p指向了该连续存储单元的首地址。
在初学C语言过程中,处理数据的过程都是从键盘上输入数据,在经过运行后让结果显示在屏幕上。在程序的执行过程当中,所处理的数据都是保存在内存中的。而内存只是临时保存数据,当程序运行结束之后,输入的数据和运行的结果都会丢失。要想达到永久保存数据和重复使用数据的目的,需要将数据以文件的形式存储在外部存储器上。
ANSIC标准规定C语言处理文件采用缓冲型文件系统,在缓冲型文件系统中,每个被使用的文件都在内存中开辟一个区,用来存放文件的有关信息,这些信息保存在成为FILE的结构类型的变量中[5]。读写文件要通过文件指针来实现。只要是指针指向一个C文件,便可以通过该指针变量实现对文件信息的访问。如程序5所示:
该程序利用文件指针fp将磁盘文件a.cpp的内容输出到屏幕上,实现了磁盘文件的访问。
通过以上介绍,指针的重要作用包括:利用指针可以提高程序的执行效率,灵活的实现字符串操作,实现对文件的访问等等。因此,指针在C语言中具有重要的地位,学好指针并灵活的使用指针进行编程,是是否掌握好C语言的一个重要标志。
[1]姚合生.C语言程序设计教程[M].北京:清华大学出版社,2008.
[2]谭浩强.C程序设计[M].北京:清华大学出版社,2005.
[3]李霞.C语言指针的应用[J].科技创新导报,2009(4):21-23.
[4]汪明光.C++语言中函数指针的分析与应用[J].巢湖学院学报,2006,8(3):30-34.
[5]苏小红,陈惠鹏,温东新,李秀坤.C语言程序设计教程[M].北京:电子工业出版社,2004.