C语言中指针的研究与总结
荆楚理工学院计算机工程学院 湖北·荆门 448000)
摘 要 指针在c语言学习中起着举足轻重的作用,c语言学的好不
好关键在于对指针的掌握。本文介绍了指针学习的现状、引入指针
的作用,并对c语言指针中较易混淆的概念进行了详细阐述,最后
探讨了指针与数组、函数的关系和使用方法。
关键词 指针 c语言 数组 函数
study and summary on pointer in c language
li xiangqin
(school of computer science, wuhan university, wuhan, hubei
430079;
school of computer engineering, jingchu university of
technology, jingmen, hubei 448000)
abstract pointer in c language learning plays an important
role, the key is to master the pointer in c language. this
article describes the learning status of pointer, the role
of introduction of the pointer, and c language pointer more
confusing concepts were elaborated, and finally explore the
relationship between pointers and arrays, functions, and use.
key words pointer; c language; array; function
0 引言
指针是c语言的精华,也是大学《c语言程序设计》①课程教学的
重点与难点。通过使用指针变量可以较方便地使用字符串、数组,
可以表示各种数据结构,从而能够编写出执行效率高、可读性强的
程序,它在很大程度上增强了c语言的功能。
对于一个不涉及指针、只有程序设计结构、函数和数组的程序,
许多学生在分析它时还觉得得心应手,一旦引入了指针,便不知所
措。究其原因,对指针的理解只停留在表层,没有从较深层次去理
解。指针的概念本身比较复杂,涉及指针与地址、普通变量与指针
变量、指针与函数、指针与数组,使用也比较灵活,需要多思考、
多总结、多上机,在实际操作中才能逐渐掌握。因此,如何学好c
语言中的指针成了一个值得研究的课题,下面就几年来在实践教学
过程中存在的想法进行总结和学习。
1 引用指针的作用
通过定义指针变量可以确定存储单元的地址和类型,如有int i,
*p=&i;则变量i与*p是等价的,在程序中可以用变量i和*p两种
方式来访问存储单元。因此,指针变量是一种新的访问存储单元的
方法,它的作用主要表现在三个方面:
(1)能够突破变量作用域的限制。程序中通常把一部分代码放在
一个函数中,基于函数的封闭性,有些操作我们不能在它的外部执
行,比如利用函数交换两个实参的值。当使用指针变量作参数时,
实参传递的是对应存储单元的地址,若利用形式参数直接访问对应
存储单元,将会打破变量作用域的限制,可以在函数中使用外部的
存储单元。
(2)可以提高函数的执行效率。形参相关的存储单元较大时,如
结构体,函数执行中用实参赋值给形参将花费较多时间和存储空
间。如果把形参的类型换成相应的指针类型,函数的执行效率则会
大大提高。
(3)使用未命名的存储单元。内存中的堆存储空间在程序运行中
是用户自己申请并指定大小,一般通过调用库函数来完成,没有变
量直接参与,只能利用指针变量间接引用的方式实现。
2 指针中较易混淆概念的理解
2.1 指针变量和指针运算符
c语言中通过变量使用计算机中的内存,变量是内存中某块存储单
元的标识,它用来存放数据,如整型变量存储整数,浮点型变量存
储实数。指针变量也是一种变量,定义一个指针变量就会有一块存
储单元与之对应,只是它存储的是地址,是某类型的地址,如实型
指针变量只能存储实型变量的地址,短整型指针变量只能存储短整
型变量的地址。
指针运算符“*”在指针中一般在两种情况下出现:第一种是定义
指针,如int i=13,*q;第二种是在赋值语句或程序执行中出现。
第一种中“*”代表该变量的类型是指针型变量,指针变量名是p,
而不是*p。第二种中 “*” 运算符表示取它指向的内容,*q表示
指针变量q所指向的变量。
比如给指针赋值,可以采用两种方法: ① int i=3,*p; p=&i; ②
int i=3,*p=&i;分别是先定义后赋值和边定义边赋值。实际教学
中许多学生在先定义后赋值p=&i中常常将p错误写成*p ,主要是
没有弄清楚概念,&i表示变量i的地址,而*p表示p指向的变量,
变量的内容是数据,数据和地址是两种不同的值。
2.2 指针变量与自增自减运算符混合
许多学生在编程过程中总是辨不清(*p)++与*p++,其实仔细分
析不难发现这两个表达式在程序执行时是有规律可循的。比如有
int i=3,*p; p=&i;成立,则(*p)++可以(下转第141页)(上
接第114页)先求括号中的内容,再进行自增运算,相当于i++ ;
而对于*p++来说,它需要考虑运算符的优先级和结合方向。由于自
增运算符++与指针运算法*优先级别相同,结合方向又为自右而左,
它相当于*(p++),可以分成两步进行计算,第一步执行*p,即i
的值,第二步执行指针移动p=p+1, p值发生改变。
2.3 数组名和函数名
数组名不能代表整个数组。c语言规定数组名(不包括形参数组名,
形参数组并不占据实际的内存单元)代表数组中首元素的地址,②
即序号为0的元素的地址。
假设a是一维数组,如int a[10]; ,数组名a代表数组首地址,
则a+i代表从首地址开始,往后偏移i个位置,即相当于是数组元
素a[i]的地址。因此,a和&a[0]都代表第一个元素的地址,同理
a+i和&a[i]都代表第i+1个元素的地址。
假设b是二维数组,如int b[4][5]; ,可以把数组b看成包含4
个元素的一维数组(b[0]、b[1]、b[2]、b[3]),而其中每一个元
素又是一个一维数组,包括5个元素。因此,在二维数组中数组名
b代表数组的首地址,b+1是序号为1的行的首地址或称第2行的
首地址。
跟数组名一样,函数名可以退化成指针。函数名是函数的地址,
也就是入口地址。
3 指针与数组、函数的关系
3.1 指针与数组
指针可以指向数组,而数组也可以是指针数组。因此,指针与数
组关系中有指向数组元素的指针和和指针数组。两者在形式上很相
近,但意义不同。
定义指向数组元素的指针与指针变量的定义相似,如int a[10];
int *p;p=&a[0]; ,那么指针变量p指向了一维数组的第一个元
素,通过指针下移可以指向数组中其它元素。而且,可以使用下标
法(如a[i]形式)和指针法(如*(a+i)或*(p+i))访问一个数
组元素。同时,在编程过程中我们经常见到形如int(*p)[10]的
表示形式,其中p用来表示指向一维数组,p所指向的对象包括10
个整型元素的数组。
指针数组是形如*p[5],它是一个数组,每一个元素都相当于一个
指针变量。为了更方便、灵活的处理字符串,引入了指针数组。二
维字符数组和指针数组都可以用来存放字符串,如果使用二维字符
数组存放则会产生一些问题,比如在定义二维字符数组时,需要规
定列数,而实际操作中,给定的各个字符串长度往往不相等,若以
最长得字符串长度来限定列数,将会浪费许多内存空间。如果以指
针数组来存放,只需将指针数组的各个元素指向相应字符串,通过
改变指针数组元素的指向就能改变各元素的值。
3.2 指针与函数
指针可以指向字符变量、实型变量、一维数组、字符串,也可以
指向一个函数。函数名代表函数的入口地址,即函数的指针,形如
c =(*p)(a,b); ,它用指针形式实现了函数的调用。
函数可以返回整型值、实型值,也可以返回一个地址。形如,int
*a(int x,int y);从形式上看,该式子与普通函数的定义比较
相似,这里函数名a前多了一个*运算符,它表示函数是指针型函
数,一般在该函数内部会再定义一个指针变量,同时给出相应的
return语句。
4 总结
指针不仅在c语言中占据核心地位,还在一些课程如《数据结构》
③中起很重要的作用,该课程里几乎所有算法的实现都离不开指
针。而且,指针也出现在许多重要考试中,如大学计算机等级考试
和计算机软件水平能力考试。因此,指针是学好c语言的关键。但
c语言概念复杂,使用灵活,大部分学生难以掌握。在上机实验中,
学生更容易出错,而且错误难以发现,这不仅要求教师在教学中能
够深刻理解指针的概念,做到灵活应用,还需要不断的进行总结、
比较和实践,而且要求教师能够利用各种教学手段与方法让学生更
容易接受和理解, 同时也要求学生能够深入理解指针的概念、注
重上机,在实践中不断学习、提高和完善。
注释
① 任正云,李素若.c语言程序设计.北京:水利水电出版社,2007.
② 谭浩强.c程序设计(第三版).北京:清华大学出版社,2005.
③ 严蔚敏,吴伟民.数据结构.北京:清华大学出版社,2004.
第二篇:c语言中指针运用的研究
C语
言中指针运用的研究
钱惠恩
(浙江工商大学统计与数学学院信息与计算科学专业,浙江杭州210018)
明嘲糟针蔗c语寓的棱心。被广泛使用。它和擞组、字缔串、函数阍教播的传i蠢有看密不可分的联系,它的使用方式与方法缀常使初
学者惑列迷惑。
D蝴】糯钟;播钟变量;基本用法;常见问题
1指针的基本概念
由计算机的工作原理我们知道,程序和数据都是以二进制代码的形式存放在内存中的,内存中的每个字节都有一个唯一地址。如果要对一个数据进行一定操作,只有按照地址先找到这个数据,才能进行下一步的操作。在C语言中,当我们定义了一个变量时,内存中就会为此变量
分配一定的存储空间,这时,就有唯一地址与此变量相对应。当我们引用变量名访问数据时,系统通过此变量名找到与之对应的内存地址,然
后在对此地址下存放的数据进行操作。对程序员来说,中间这个过程是透明的,就像是通过变量名直接访问数据一样。这种通过变量名访问内存空间中数据的方式称为直接访问。
C语言提供了这种特殊类型的变量——指针类型。这种类型的变量
和其他变量一样,定义后在内存中占据一定的存储空间,用来存放数
据,只不过这个数据将会被解释为地址。所以,指针就是指地址。对于
一个指针变量,它的定义方式为:数据类型关键字,’变量名指针变量
中存放的值为另一变量在内存中的地址,而指针变量的数据类型即其值
所指地址中存放的数据的数据类型,*则标识此变量为一指针变量。
2
C语言指针应用的优点
指针是C语言的一个重要概念,也是C语言的一个重要组成部分,正确灵活地使用指针,能帮助我们解决许多实际问题。主要有:1)指
向单变量的指针变量作为函数参数,可以得到多个变化了的值,即函数
调用可以而且只可以得到一个返回值,而运用指针变量参数,就可以得到多个变化了的值。2)指向数组元素的指针变量处理数组,可以大大
提高执行效率,所以指针使用熟练时,尽量使用指针处理数组。3)指
向字符串的指针变量构成指针数组处理多个字符串时可以节省内存空
间,还可以提高程序的执行效率。4)指向结构体变量的指针作函数参
数,可以节省时间和空间,提高执行效率。5)指向量FILE类型结构体的指针变量,可以找到与之相关的文件,从而实现对文件的访问。6)指向函数的指针作函数参数,可以使一个通用函数实现各种专用功能。
3指针使用过程中的常见问题
31指针的初始化
先看一个例子:
Int。ptr;’ptr=1;
ptr确实是一个指针,但指向哪里呢?上述代码没有将地址赋给ptro那么1将被放在哪都不知道。ptr没有被初始化,可能有任何值。不管值是什么,程序都将解释为存储1的地址。如果ptr的值碰巧为
1
200,计算机将把数据放在地址1200上,即使这恰巧是程序代码的地
址。ptr指向的地方很可能并不是所要存储1的地方。这种错误可能会导致一些最隐匿、最难以跟踪的bug。
一定要在对指针应用取内容操作符(。)之前,将指针初始化为一个确定的、适当的地址。修改以上例子为:
int。ptr=&a;
不要将”int。ptr=&a:”与”+ptr=&a;”混淆。前者是定义语句,。是指针定义符,C编译器为ptr指针分配一个指针空间,并用a的地址值初始化。
32对指针变量赋值
1)指针变量的赋值只能赋予地址
20xx年1111
先看一个例子:
intb;int。q;q=&b:
程序中是不允许把一个数直接赋予指针变量的。指针变量的赋值只
C语言中提供
了地址运算符&来表示变量的地址。其一般形式为:&变量名:如&aa的地址。
2)不同类型的指针不能相互赋值先看一个例子:
int’p;
doublea=5,‘q=&a;p=q;
指针是有具体类型的,在给指针赋值时,不但要求是地址,而且应类型相符的变量或常量的地址。以上语句中在p=qi误,因为P是一个整型指针,只能存放int型数据的而q指向了一个双精度型变量,里面存放double型数据。二者匹配,因此在编译时会发生错误。初学者往往注意了将地址赋3)指针在函数之间的传递先看一个例子:
voidfun(int。X,int。计(printff%d,%d,’x,+啪;
。×=3;。V=4;
malnO自ntx=1,y=2;fun(&y,&蛐:
printffI%d,%硝,X,”;}
在C语言程序中,可以通过传递指针的方式,在被调用函数中直接ainO在调用函数funO的同时,把变量Y与X的地址传递给指针变量XY,注意mainOdP的X、Y与funO中X、Y是不同的。前者代表普通变funO函数中,输出。Xy的值,结果为2,。Y的值为1.之后改变+x与+y的值,针返回给mainO函数,从而改变了Y与X的值,因此第二次输出4,3。
4总结
C语言指针的使用灵活,大多数初学者在实际编程中很容易出错,错误往往又难以发现,因此在教学后期建议学生大量地上机调(参考文献】
【1】谭浩强著.C程序设计肼1.第=版_E京:清华大学出版社,1999.
【2】RDbc廊ES著.C谮富的科学稻艺术fM】.翁惠玉等译.北京:机械正业出版社,2005.【3lKd'aiskaaBW,RdtehieDM著.c程序设计语富fM】.第2版.徐宝文等译.北京:gt撤I业出版社,2005.
能赋予地址,不能赋予任何其它数据,否则将引起错误。变示变量该是一个与该指针这条语句上存在错地址。类型不相值给了指针,而忽略了其类型。
改变调用函数中变量的值,达到函数之间数据传递的目的。主函数
m与量,后者为指针变量。第一次输出数据值发生在就相当于输出通过指结果为而且这种试程序,以弄清一些细节,并积累经验,为后续课程打好坚实的基础。