c语言数组与指针的实验报告,C语言中指针与数组的恩怨浅析

摘要:在C语言中指针是教学中最大的难点,在学习初,尤其对数组和指针的相关语法感到非常“纠结”,常常一头雾水。那么,指针和数组到底有什么关系呢?在我们还不了解的时候,我们不防先这样告诉自己:“它们之间没有任何关系。”该文将帮助您辨明指针与数组之间的“思思怨怨”。

关键词:指针;数组;指向;常量;变量

中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2013)34-7795-02

在C语言中,指针和数组是两个密不可分的概念,所以在我们正确区分它们的恩怨纠葛之前,先要正确理解一下“指针”和“数组”的概念。

1 什么是指针

关于“指针”一词,在K&R中是这样描述的:指针是一种保存变量地址的变量。所以一量说到“指针”,我们就很自然的想起“指针变量”,就要把它当作变量的意思。比如:char *p1;int *p2; float *p3;double *p4,这最基本的写法。但是,这只表示该指针指向某类型的数据,而不表示该指针的类型。说白了,指针都是一个类型:四字节无符号整数。

以C语言标准中最初出现“指针”一词的部分,有这样的一段描述:

指针类型(pointer type)可由函数类型、对象类型或不完全的类型派生,派生指针类型的类型称为引用类型。指针类型描述一个对象,该类对象的值提供对该引用类型实体的引用。由引用类型T派生的指针类型有时称为“指向T的指针”。从引用类型构造指针类型的过程称为“指针类型的派生”。这些构造派生类型的方法可以递归地应用。

解释一下上面的话,也就是说,指针类型不是单独存在的,而是依附于派生出它的基类型,也就是上面那段话中最关键的一句:“由引用类型T派生的指针类型有时称为‘指向T的指针’”,即可以有“指向int的指针类型”、“指向float的指针类型”等等。

既然“指针类型”也是类型,那么就该和基本数据类型中的int、float、double 一也存在该类型的变量,以及该类型变量所对应的值,即“指针类型变量”和“指针类型的值”。

2 C语言中数组值得注意的地方

什么是数组?大多数的教科书上是这样描述的:“数组是一组有固定数目的、有序的、相同数据类型的元素的集合。”但我想说两点,我所理解的数组。

1) C语方中只有一维数组,而且数组的大小在编译期就必须是一个明确的常量确定了下来。那你一定会问,那多维数组呢?其实,多维数据只是由一维数组“仿真”出来的。也就是说,数组的元素可以是任何类型对象,那么我们只要把一维数组中的每一个元素都定为另一个一维数组,那多维数组就被仿真出来了。

2) 要想操控一个数组,我们只要确定两件事,一是确定该数组的大小,二是获得指向该数组下标为0的元素的指针。有的时候,对数组的操作是靠下标运算来控制的,但这只是一个表面现象,实际都是通过指针进行的。也就是说,数组的下标运算等同于一个对应的指针运算,所以我们完全可以依据指针行为定义数组的下标行为。看来我们不能说“指针”和“数组”之间没有任何关系。但是,我依然要强调,指针就是指针,数据依就是数组。

3 指针和数组并不是相等的

是的,指针就是指针,数据依就是数组。它们并不是相等的。为了说明这个概念,请看下面的声明:

Int x[5];

Int *y;

x和y能互换使用吗?可以吗?它们都具有指针值,也就是说他们的值都是个地址,它们都可以进行间接访问和下标引用操作,尽管这样,答案仍然是,它们不能互换使用,它们存在着相当大的区别。

在这里,x的值是一个常量,指向存放数组x这段空间的起始位置。而声明指针变量时,编译器只为指针本身保留内存空间(32位系统下,永远占4个字节,其值为某一个内存的地址。)它并不为任何整型值分配内存空间,而且,在没有对其初始化之间,该变量并未被安排指向任何现有的内存空间。当然,如果它再是一个auto,它甚至于根本不会被初始化。

有了上面的定义,让我们来看看这几个表达式,看看它们是不是合法的:

*x 它是完全合法的;

*y 它是非法的,因为这是将访问内存中某个不确定的位置,计算机可没那么聪明;

y++ 它也可以通过编译;

x++ 它不能通过编译,因为x是数组名,数组名是一个常量,是不能进行自增自减运算的。

4 以指针的形式访问指针和以下标的形式访问指针

让我们举个小例子:Char *p=”abcdef”;对于这个定义,如果现在我想读取字符‘e’我们要怎么处理呢?有两种方法:

1) *(p+4):这是以指针形式来读取的,先取出p里存放的地址(假定地址是Ox1111ff00),加四个字符的偏移量,新地址应该是Ox1111ff04,然后取出Ox1111ff04这个地址里取放的值,这个值就是我们要读取的’e’。

2) p[4]:这是以下标的形式读取的,先取出p里存储的地址值;再加上中括号中四个元素的偏移量,计算出新地址,然后从新地址中取出值来。我们可以看到,这两种方法并没有本质的区别,只是表现形式即写法的不同而已。

5) 以指针的形式访问数组和以下标的形式访问数组

再来看下面这个例子:Char x[]=”123456”; 对于这个定义,如果现在想读取字符‘5’我们要怎么处理呢?也有两种方法:

1) *(x+4):这是以指针形式来读取的,x这里代表的是数组元素的首地址(假定地址是Ox1111ff00),再加上四个字符的偏移量,得到新地址Ox1111ff04,然后取出Ox1111ff04这个地址里取放的值,这个值就是我们要读取的’5’。

2) x[4]:这是以下标的形式读取的,x作为数组首地址,再加上中括号内四个元素的偏移量,计算出新地址,然后从新的地址中取出值’5’。

还有一件事请大家注意,这里所说的偏移量带表的是元素个数,而不是字节数,比如上面例子中偏移量为4,是指4个元素,而不是4个字符,只是因为一个字符本来大小就是1个字节,所以地址从Ox1111ff00,偏移后变成Ox1111ff04,如果是整型或其它类型就要重新计算了。

通过上面的分析,我们对指针和数组又了更深层次、更清晰的了解,指针和数组真真的、的的确确的是两回事,在应用过程中一定不能把它们混淆,但是我们可以以指针的形式访问指针、以下标的形式访问指针,当然也可以,以指针的形式访问数组、或以下标的形式访问数组。当然仅仅是理解还是不够的,我们必须通过大量的实践才能做到真正的运用自如。

参考文献:

[1] 谭浩强.C语言程序设计[M] .北京:清华大学出版社,2010.

[2] 杨智明.C语言指针使用分析[J].保山学院学报,2012(2).

[3] 赵忠孝,杨亚蕾.对C语言指针教学问题的探究[J].计算机教育,2009(19).

[4] 徐辉,王安民.关于C语言中使用指针作为函数参数的问题[J].电脑编程技巧与维护,2009(18).

[5] Andrew Koenig. C陷阱与缺陷[M] . 北京:人民邮电出版, 2011.

[6] 前桥和弥.征服C指针[M] .北京:人民邮电出版, 2011.

[7] Kenneth A.Reek.C和指针[M] .北京:人民邮电出版, 2010.

[8] 陈正冲. C语言深度解剖[M] .北京:北京航空航天大学出版社, 2011.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值