第20卷第2期1998年6月
武汉水利电力大学(宜昌)学报
J1of Univ1of Hydr1&Elec1Eng1/Y ichang
Vol120No12
J un11998
C/C++指针变量的使用原则与注意的问题Ξ
涂德重
(电气工程系)
摘 要 用实例详细地阐述了C/C++语言指针变量的使用原则和方法,同时还指出了实际应
用中需要注意的问题.
关键词 C/C++语言; 指针; 指针变量
分类号 TP312
目前,程序设计语言的应用越来越普及,而C/C++语言具有独特的优点,因而更加受到软件开发者的欢迎和喜爱.然而要真正用好C/C++语言也决非易事,必须下一番功夫.C/C++语言中最灵活最具有特的就是指针变量.如何理解和使用好指针变量是编程人员编写高质量的软件的关键.
在程序设计中,可以定义变量本身,也可以定义指向变量的地址指针—指针变量,即变量的物理存储空间.这样就可以使编程人员能够对数据结构中所定义的链结构类型(如链表、栈、队及树等动态分配单元)得以实现,从而对它们进行存取操作,特别是C++的类和自定义结构的存取更是如此.要高质量地、有效地开发一些应用程序和系统软件必须很有效地使用指针变量.一个编程人员对指针及指针变量掌握和熟练的程度从某种角度来说决定了他编写程序的高低.
1 指针变量的定义
指针类型的变量,它用来定义指向对象的指针,也就是定义指向分配对象存储区域的地址.它通常说明某个变量具有指针类型的一般格式为type 3指针变量名;或者更精确地定义为type[修饰符]3指针变量名.这里[]方括号为可选项,可有可无.缺省时为近指针.type为指针指向的数据类型.修饰符可以是near,far,huge.它们分别是近、远、巨大三种指针.
near指针为一16位指针,它存取的区域只是DS寄存器段,范围为64K.而far指针可以在内存中任意段设置DS,而段内偏移可取0~0FFFFH的任意值(每段64K).而huge指针为巨大指针(绝对指针),它可以在内存中任意移动和设置.
type数据类型为C语言中所规定的数据类型,它有基本类型和构造类型,指针使用说明方法如下:
Ξ收稿日期:1997-09-23
涂德重,高级工程师,硕士,从事计算机管理及软件开发工作.武汉水利电力大学(宜昌)电气工程系(443002)
float 3fp ; //说明fp 为指向float 类型对象的指针变量
struct node 3treep ;
这里 node 为构造类型,定义如下
struct node {
int information ;
struct node 3father ,3brother ,3son ;
};
这样,就定义了treep ,它指向构造类型node 对象的指针变量.
下面,列举一些常用的指针变量的定义方法.
int 3i p ; /3定义指向整形变量的指针3/
int 3f i p (); /3定义指向函数返回的整形变量3/
int (3pf i )();//定义指向一个函数的指针,此函数返回一个整形变量
int 3p[n ]; //定义整形指针数组p[n ],这数组每一元素为一指针
int 3(3pf pi )(); /3定义一个指向函数的指针,而该函数又返回一个指向整数的指
针3/
int (3p )[n ]; /3定义一个指向n 个整形元素的一维数组指针3/
int 33p ; /3定义p 为二次变址指针,p 为指针变量,它指向一个整形数的指
针3/
当然,仿此还可以定义3次变址,4次变址指针,但多次变址指针在程序中很少使用.2 指针变量的使用方法
原则上讲,凡在程序中使用变量的地方都可以使用指针变量代替.但是有些地方变量结构太大或者使用变量影响程序的执行效率时,一般使用指针变量为好.下面就笔者的体会作一概括.
(1)用指针变量提高程序的执行速度和效力
例1 定义一个学生变量
struct student{
int number ; /3定义学号3/
char name[10],sex[4]; /3定义姓名、性别3/
int fen ; /3定义学生成绩3/
struct student 3prep ,3nextp ;
/3定义指向前一学生的前趋指针,指向后一学生的后继指针3/
};
如果对此记录进行排序操作,显然可以想到指针进行运算比较方便,只须改变记录中前趋及后继指针变量的值即可完成这一排序工作.这一点显然比其他的运算快速简便,其功效和速度是显而易见的.为此,可以编写如下的程序片断
insted =readstud (); //读一学生记录,此记录指针送入insted 这一//指针变量 addstud (insted );/3进行排序操作3/
3
4第20卷 第2期 涂德重 C/C++指针变量的使用原则与注意的问题
这里定义addstud ()函数如下
void addstud (struct student 3p )
{ next =head ; //head 为头指针,指向第一条记录的地址
while ((next →number <p →number )&&(next →nextp !=NULL ))
next =next →nextp ;
if (next →number <p →number )next =next →nextp ;
p →nextp =next ;p →presp =next →prest ;
(next →prest )→nextp =p ;next →presp =p
}
(2)用指针变量对动态数据结构进行分配和存取
动态数据结构在实际应用中是很多的,如链表、动态数组、树、图等等.这些数据结构事先不知道它的大小,必须在程序运行过程中才能知道,因而必须由程序自己动态分配存储空间.
例2 现以三维数组来说明怎样用指针变量来建立一个动态分配函数的[2]. float 333Gen -3d -float (i nt n 1,i nt n 2,i nt n 3)
/3对三维数组动态分配存储空间,n 1,n 2,n 3分别为数组 arr[n 1][n 2][n 3]的维数3/
{
float 333arr ,3p ,33q ;
i nt i ,j ;
arr =(f l oat 333)malloc ((unsigned )(n 13sizeof (float 33)+n 13n 23sizeof (float 3)+ n 13n 23n 33sizeof (float )));
/3n 13n 23n 33sizeof (float )是存放浮点数维元素的byte 数目.n 13n 23sizeof (float 3)是要存放指向部分浮点数组的指针byte 的数目
n 13sizeof (float 33)是要存放指向部分浮点数组元素指针的指针的
byte 的数目
if (arr =NULL ){
printf (″分配错误:没有足够的内存存放数组元素1/n ″
); return (NULL );}
/3以下对指针赋值3/
q =(float 33)(arr +n 1);
p =((float 3)(q +n 13n 2);
for (i =0;i <n 1;i ++){
arr [i ]=q ;q +=n 2;
for (j =0;j <n 2;j ++{
arr [i ][j ]=p ;p =n 3;}
}
return (arr );}
上述 分配空间结构如下:
4
4 武汉水利电力大学(宜昌)学报 1998年6月
arr [i ]arr [i ][j ]arr [i ][j ][k ]
一维数组空间二维数组空间三维数组空间
(3)用指针变量提供编程的灵活性与方便性
例3 在下面改变字串顺序的例子中可以看出指针操作的方便快捷
void str -invert (char 3s )
{static char 3p ;
if (!3s )return ; //字符空串,不操作
p =s ; while (3p )p ++;p --; //指向字符串尾
while (s <p )3s ^=3p ,3p ^=3s ;3s ++^=3p --; //指针的逐渐改变} //进行排序过程
试想,如果不用指针程序将会复杂得多.
(4)用指针变量对显示缓冲区或内存中任何区域进行存取
例4 保存中断向量程序片断
fp =fopen (″CL EARM EM 1DA T ″,″wb ″); /3保存到文件CL EARM EM 1DA T 中
3/
if (fp =NULL )printf (″file not exict !″
); vector =(unsigned char far 3)0x 0; /3数值0转换成指针3/
for (i =0;i <1024;i ++) /3循环写入1024字节3/
(3(vector +i ),fp );
fclose (fp );
通过以上举例说明指针变量的应用原则是:(1)实现对动态数据结构的存取;(2)用函数指针来增加语言的表达能力和编程的灵活性;(3)提高程序的运行功效和速度;(4)对内存区域和无名区域的存取.
3 使用指针变量要注意的问题
虽然指针变量有很多的优点,给程序设计带来很多方便,但是指针变量也会带来一些麻烦,稍有不慎就难以达到预期的效果,严重时可导致系统崩溃.这一点必须加以小心才是.下面分别谈谈指针在程序设计时要注意的问题.
(1)必须对指针变量赋初值
指针变量虽然是指向某类型变量的地址,但在程序使用前必须给以赋值.如果不赋值,它可以随机设置,显然,这种错误是严重的.
(2)必须对指针变量所指的对象分配足够多的存储单元
对指针变量所指的对象赋值时,该变量必须有所指.换言之,必须为该变量分配其类型大小那样多的存储空间.如果过少或甚至未分配将导致严重后果.
(3)不判指针为空而进行操作
如果有一个指针类型变量,它的值为NULL ,则它不指向任何对象.如果强制对它所指的对象进行操作,则可能发生以下的情况:或者禁止读写;或者只允许读出而禁止写入;或者
5
4第20卷 第2期 涂德重 C/C++指针变量的使用原则与注意的问题
既允许读出又允许写入.在允许存取的情况下,NULL 对应于0地址,它所指向的对象所在存储区域并不在程序管辖范围内.对这种不合法存储区域赋值,后果之严重是不难想象的.
(4)函数按地址引用时参数的误用
对于函数的参数,一般有按值引用与按地址引用两类.当按值引用时实参的值临调用函数时被计算而传递给相应形参.对于按地址引用参数时,将把实参的地址传递给相应形参而进入被调用函数,当从函数返回时,该实参的值可能被改变而得到新值.这时不应混淆传值和传地址的概念.
(5)不重视关于指针类型的警告信息
当使用TURBOC 编译器时,除了提供查出各种程序错误信息之外,还提供了关于程序的大量警告信息.当然相当部分的警告信息对程序的运行所施加的影响是微乎其微的.然而关于指针类型的警告信息不能等闲视之,必须高度重视.例如,不可移值的指针类型转换与比较、有正负符号字符与无正负符号的字符之指针的混用等等.
(6)其他易错的情况
下面给出其他几种容易发生的错误情况
①例如:struct window -type 3winp ;
winp =malloc (sizeof (struct window -type ));
这里必要的是进行强制类型转换,使winp 是指向window -type 类型对象的指针,这可以使用下列语句
winp =(struct window -type 3)malloc (sizeof (struct window -type ));
②对指针理解有误之例
main () { int x ,3p ;x =10;p =x ;printf (″%d ″,3p );}
这里打印的将不是x 的值,而是以x 值为10的地址的存储字的内容.
4 结语
由以上归纳可以看出指针类型变量在程序设计中有很多的优点,在使用中又有极大的灵活性、方便性.程序开发者必须熟练地掌握,巧妙地运用之.这样才能设计出赏心悦目、妙不可言的程序画面和程序功能.可见,指针类型变量确实是C 语言中的精华部分,应高度重视,多花点精力学习并掌握之.
参考文献
1 谭浩强1C 语言程序设计1北京:清华大学出版社,19941158~212
指针变量本身有地址吗2 宋世德1C 语言多维动态数组的实现1电脑编程技术与维护,1995(10):18~20
3 Atkinson L ,Atkinson M 1C/C ++快速进阶教程1陈晰,梁帆译1北京:科学出版社,19951232~240
(下转第54页)
6
4 武汉水利电力大学(宜昌)学报 1998年6月
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论