学习C语言中的指针类型

时间:2022-10-11 11:30:11

学习C语言中的指针类型

摘要:结合我院学生十年来参加全国计算机等级考试(C语言部分)情况,通过分析成绩分布与题型关系,我们发现指针方面的题型失分率最高。在此基础上结合教学实际,本文提出学习指针知识的方法和顺序过程,并将其应用在C程序设计课程教学中,取得了较好的实践效果。

关键词:等级考试;指针;指针类型;指针常量;指针变量;数组与指针;行指针;列指针

据统计,十年来我院有450多名学生先后参加了全国计算机等级考试。我们对C语言笔试和上机成绩分析发现,指针类型方面的题型出错率最高,占平均错误率的60%左右,这说明指针知识的学习是学生学习C语言的难点。指针类型是一种特别的数据类型,与C语言中其他数据类型相比,既抽象又复杂,同时有关C语言的教程类图书对指针论述的差别也给学生带来了困惑。根据笔者的经验,学生只有掌握了与指针类型相关的基础知识,才能较好地理解、掌握和应用指针数据类型。

1计算机内存储器地址的编码方法

欲学好指针类型,首先要知道计算机内存储器地址的编码方法。计算机内存储器里存储的信息都是由1和0构成的二进制数来表示,每一位二进制数位是表示信息的最小单位,计算机技术规定在内存储器里用八位二进制数位来存储信息,这八位二进制数位叫一个字节,即在内存储器里是以字节为单位存储信息的,如大写英文字母A,在内存储器里用01000001表示。把能表示八位二进制数的存储空间叫一个字节存储单元。

在实模式下“为了访问存储器的不同字节存储单元,每个字节存储单元人为给以一个编号,叫存储器的地址,地址从0开始编号,顺序地每次加1。”如PC计算机配置512MB内存条,其存储空间地址编号范围用十六进制数表示为00000000~3FFFFFFF,即十进制数的范围为:0~536870911,有536870912个字节存储单元,相当于可存放536870912个英文字符(半角字符)。配置1G内存条,其存储空间地址编号范围用十六进制数表示为00000000~7FFFFFFF,即十进制数的范围为:0~1073741823,有1073741824个字节存储单元,相当于可存放1073741824个英文字符(半角字符)[1]。

2存储单元的地址

C语言中数据有基本类型(字符型、整型、长整型、实型、枚举型)、构造类型、指针类型等。不同数据类型在内存中存储时,占用的字节数不同,如字符型需要1个字节空间,整型需要2个字节空间,长整型需要4个字节空间等。把不同数据类型存储时需要的N个字节看成一个整体,叫一个存储单元。对字符型N=1,整型N=2,长整型N=4等。对1个字节构成的存储单元,其字节单元地址编号就是该存储单元的地址,对多个(N>=2)字节构成的存储单元,其低字节单元地址为该存储单元的地址,也叫存储单元的首地址[1-2]。

3指针类型

语言中的指针类型有指针常量和指针变量。指针常量简称为指针,即存储单元的地址。可以认为配置不同容量的内存,其指针值的范围是不同的,但都是

作者简介:杨加义(1960-),男,高级讲师,研究方向为嵌入式系统、Matlab仿真技术、Matlab语言与学科教学。

从0起始的。每个存储单元的指针值都是固定不变的。指针变量就是用来存放指针的变量。指针变量是一种较特别的变量,它的值是一些特定的整数值,不是任何整数(如负整数)都可以存放到指针变量,指针变量与整数加减运算也不同于数学中的运算方法。指针变量也有自己的内存空间,空间的大小由编译器决定,在Turbo C 2.0下是2个字节,在Visual VC++下是4个字节[1,3]。

4变量的指针

在编译C语言程序时,要在内存为各种变量分配相应的存储单元,相应的变量名称对应着存储单元的首地址,这首地址就是变量的指针。可以将一变量的指针赋给一指针变量(存到指针变量代表的存储单元中),这时就说指针变量指向了该变量(也可以说指针变量指向了该变量表示的存储单元)。对存储单元的存取操作即可以用变量名,也可以通过指向该变量的指针变量来进行,这要用到指针运算符“*”[3]。

5指针变量类型和它所指向的数据类型

指针变量的类型以声明它时其前面的“*”为标志,无论指针变量指向何种数据类型,它所占用的内存空间大小是一定的(如2个字节),这与其他数据类型的变量所占有的内存空间大小一定一样,所以指针变量的类型就是指针类型,与它所指向的数据类型无关。有资料把可指向不同数据类型的指针变量说成有整型指针(int *)变量、实型指针(float *)变量、字符型指针(char *)变量等,笔者觉得没必要。如果非要这样说,理解成指针变量可指向什么数据类型变量就叫什么数据类型指针变量为好,如 int *p;的声明p可以指向整型变量,说p是整型指针变量为好。

声明指针变量时,还要声明允许指针变量指向的数据类型,这由声明指针变量时“*”前面的“基类型”决定。指针类型加减整数运算时移动的位置大小由指向的数据类型来决定。指向同一种数据类型的不同指针变量间可以进行加减或大小比较运算,指向不同数据类型的指针变量不能进行加减运算或大小比较运算。指针变量一旦被“基类型”声明可指向某种数据类型,就不能再指向其他别的数据类型。

指针类型中的指针变量还可进行自增自减运算,而指针不能。指针变量既可以是左值,也可以是右值,指针只能是右值。由指针、指针变量与运算符构成指针类型表达式。下面说的“&”作为单目运算符时与一个变量结合就构成指针表达式,如&a,&p等,而“*”作为单目运算符只可与指针类型结合,构成指针类型指向的数据类型表达式,如有:

int *p,a,b;

p=&a;

b=*p;

*p=10;

*&a=20;

其中“b=*p;”的*p就是整型表达式,也是一个整型变量,&a是指针类型表达式,*&a是一个整形表达式,也是一个整形变量。

对于指向指针变量的指针变量,还要复杂些[3]。

6 “&”和“*”运算符

C语言中有“&:按位与运算符,是双目运算符,结合性是由左到右”和“&:取地址运算符,是单目运算符,结合性是由右到左”,有“*:乘法运算符,是双目运算符,结合性是由左到右”和“*:指针运算符,是单目运算符,结合性是由右到左(“*”在声明指针变量时也用到了)”。

对于取地址运算符&只能与一个变量结合构成指针类型表达式,如有变量name,则&name就得到变量name的指针。

对于指针运算符*,意义是“取其指向的内容”,这里说“取其指向的内容”不是指存储单元里存放的值,而是表示指针变量指向的变量。在有的书中说“例如:&a为变量a的地址,*p为指针变量p所指向的存储单元的内容(即p所指向的变量的值)[1]”,这种说法值得商榷。笔者认为用“*p代表指针变量p所指向的存储单元(即p所指向的变量)”的说法比较合适,更直接说 *p是一个变量,因为*p可以是左值。如下代码:

void main()

{int a,*p;

p=&a;

*p=10;

printf("%d,%d\n",a,*p);

*&a=20;}

输出a和*p的结果都为10,说明*p与a等价。通过 *&a= 20;语句还可以改变a的值,也说明 *&a与a等价,*&a可以是左值[4]。

上一篇:高职JavaEE编程技术课程改革的探索与实践 下一篇:C#程序设计在非计算机专业计算机基础教学中的...