开篇:润墨网以专业的文秘视角,为您筛选了一篇浅谈C语言中的指针范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!
摘要:指针是C语言的一个重要概念,文章对指针基本概念和使用作了简单介绍,总结了指针在使用过程中常犯的错误,讨论了出错的原因,指出正确使用指针的方法,并阐述了C语言中的指针与数组、函数等结合起来的指针及其应用。
关键词:C语言;指针;数组;函数
中图分类号:TP312文献标识码:A文章编号:1009-3044(2008)35-2546-04
On the Pointer in the Language "C"
ZHANG Lin-mei1, SHANG Yong-qiang2
(puter Science Department, Xinyang Agriculture College, Xinyang 464000 ,China; 2.Administration Office, Xinyang Agriculture College, Xinyang 464000 ,China)
Abstract: C language pointer is an important concept,This article made a brief introduction on the basic concept and use of pointer, summed up mistakes of the pointer used in the process,discussed the causes of the problem,pointed out the proper use of the pointer approach,and elaborated on the array of pointers in the C language, such as combining the functions of the pointer and its application.
Key words: C language; pointer; arrays; function
1 引言
C语言是使用最广泛的程序设计语言之一,它以功能强大,语言简练,编程灵活等特点为广大程序设计人员所青睐,但对初学者是有一定难度的。尤其是指针,它既是C语言的一个重要特色,又是C语言的重点和难点。正确而灵活的使用指针,可有效的表示复杂的数据结构、动态分配空间、方便引用字符串和数组、在函数调用中获得多个返回值、并且可以直接处理内存地址等等。正是因为指针太灵活,一旦指针使用不当,将会导致程序出错,甚至造成系统崩溃。因此,要编写出正确高效的程序,正确理解和使用指针,以及了解指针使用的常见错误是很有必要的。
2 指针的理解和使用
2.1 指针的理解
理解语言指针的基础就是牢固树立指针就是地址的概念。明确地说,指针常量就是地址常量,指针变量就是地址变量。
我们先来看看指针常量:
1) 若a是整型常量,则&a表示是a的地址,因为常量的地址在内存中是固定的,因此,是&a指针常量。
2) 对于数组来说,只写数组名表示数组的首地址,而数组在内存中的位置是不能改变的,所以它也是指针常量。
3) 对于字符串常量来说,直接写出某一字符串就是表示是该字符串的首地址,这是许多教科书上未能提到的。字符串常量在内存中有固定的位置,字符串常量的地址也属于指针常量。
4) 对于某个函数来说,它在内存中的地址也是固定的。这样,函数的地址也属指针常量,在C语言中,函数名可以表示函数的地址。
再来看看指针变量:
指针变量就是地址变量,就是说,它是用来存放某一类变量地址的变量。有此概念以后,我们就容易理解指针数组的元素是用来存放变量地址的。同样,在处理链表、二叉树这类递归数据结构时,相应的结构中应存放其它结点的地址从而形成链接的成员变量,即该成员变量应是地址变量,必须用指针变量来刻画。
对于指针变量来说,C语言提供了“ * ” 运算符,它表示取该变量的内容,而当指针变量是指向某一函数时,这时的“ 取内容” ,应广义的理解,即执行相应的函数。
2.2 指针的使用
在程序中定义一个变量,C语言编译系统就会根据该变量的数据类型,为其分配相应的存储单元,类型不同所分配的存储单元的字节数也是不同的。指针变量是一种特殊类型的变量,定义一个指针类型后,C语言编译系统便会为该指针变量分配一个存储单元,用于存放相应变量的地址。使用该指针变量时,必须保证该指针变量指向一个明确的存储单元,即被赋值。例如:
int *p,i=2;
p=&i;
使用指针时,常常涉及到两个运算符:
1) &:获取存储单元的地址
2) *:获取指针变量所指向的存储单元的内容
例如,&i表示变量i的地址,*p表示指针变量p所指向的存储单元的内容,即变量i的内容为2。
2.3 指针变量的类型
指针变量与一般变量一样,也有类型。指针变量的类型是指针所指向的数据的类型,我们也称指针变量类型为指针变量的基类型。指针变量的基类型不仅仅是指所定义指针变量的类型修饰符,同时还包含该指针变量是对多大的存储空间进行解释。例如:
int *p1,(*p2)[3],(*p3)[2][3];
其中,p1可指向1个int 型的存储单元,p2可指向3个int型的存储单元,p3可指向6个
int型的存储单元。因此,p1+1是p1指针向下移动2个字节(基本整型占用2个字节),p2+1是p2指针向下移动6个字节(p2指向3个int型的存储单元,每个存储单元占用2个字节,即3×2),p3+1是p3指针向下移动12个字节(p3指向6个int型的存储单元,每个存储单元占用2个字节,即6×2)。
我们知道可以有下列语句定义指针与数组:
int * p ; / * 指向整型的指针* /
int a[3] ; / * 整型数组* /
那么把两者结合起来会怎么样呢?
int * pa[3] ;
是定义成数组呢?还是定义成指针呢?回答这个问题的关键在于运算符的优先级。因[ ]的优先级高于* ,加上括弧后定义变成
int ( * (pa[3]) ) ;
所以pa究竟定义成什么,只要从内层依次往外层看就可以了。即pa是数组,由三个元素组成,每个元素是指针,是指向int 型的指针。综合起来,pa是由三个指向int型的指针所构成的数组。
所以对于一个复杂的定义,我们可以按以下步骤来理解它:
1) 根据优先次序,加上必要的括弧,使变量名在最内层。
2) 从最内层开始依次往外层看,写上所看到的内容。
如: * ―指向×××的指针
[ n] ―有n 个元素的数组
() ―返回×××的函数等等
例如,对于int * * pp ;
1) 加括弧int ( * ( * pp) ) ;
2) pp 是指针,是指向指针的指针,该指针是指向int 型的。
3) 所以,pp 是指向int 型指针的指针。
注意,这时不要被两个* 所困惑。pp 也只不过是一个指针变量而已。请看下面的操作: 如图1:
int i ;
int * p ;
int * * pp ;
pp = &p ; / * 把指向int 型的指针变量p 的地址放入pp 所在的内存单元* /