您的位置:首页 > 编程语言 > C语言/C++

C语言指针和数组理解

2012-09-10 00:40 274 查看
今天看《狂人C》关于指针这一章,感觉自己C语言对于指针的理解确实更进一步了,作者代码命名和格式虽然不怎么样,但是确实理解透彻,讲得通俗,对于我这样的入门级选手还是不错的。

首先关于指针的几个结论的理解:

指针存储大小与操作系统位数有关,一般装的是32位的操作系统,那么指针输出来显示的便是32位,合4字节,64位边是8字节,特别注意的是这个存储空间与存放数据的大小不是一个概念,这点直到今晚前,我都还有点犯迷糊,,文字不直观,下面贴图说明:



图 1

输出整型变量str的地址和其后面两个连续的地址,会发现0xbff4017c和0xbff40180相差了四个字节,这四个字节是什么呢?之前一直以为是指针存储空间需要四个字节,但其实不是的,这四个字节是因为int整型变量存储需要四个字节,所以才有了这样的差距,下面用字符型变量char贴图证明一下:



图2

会发现这里的指针之间只相差1个字节,原因就在于char型字符变量只需要一个字节来存放,所以这个差距来源与指针变量的数据类型大小,而不是指针本身的大小。个人猜想指针大小是不需要我们关心的,这个的分配应该是操作系统做的事情,编译器只是通过指针来寻址找数据。

今晚还看到一个比较震惊的运算就是[],《狂人C》里面抽象出这样一个等价式:

表达式1[表达式2]与(* ( (表达式1) + (表达式2) ) )完全等价,又因为加号“+”符合交换律,进一步推出(* ( (表达式1) + (表达式2) ) )等价于(* ( (表达式2) + (表达式1) ) ),然后推出等价于表达式2[表达式1]。绕晕了的同学可以直接看下面的例子:

也就是说在图2中的字符数组a,a[1] = 8,没问题,那根据上面的理论,1[a] = 8,这个结论刺瞎我的眼睛了,当然也等价于*(a + 1),我的理解,也就是说[]是一种运算,他会把括号外数组的地址和括号内的偏移相加然后算出地址,找到这个地址的数据取出来就完成了。

那么对于a[1],是把数组的起始地址a拿到手和偏移1相加得出地址,并获取到a[1]的数据;

对于1[a],则是把数组的起始地址1拿到,和偏移a相加得出地址,最后得出结果,这里的偏移只是我个人助于理解的词,不必纠结;

其实a[1]和1[a]的运算应该最后都被编译器解释为*(a+1)或者*(1+a),得出的结果是一样的,那么你直接运行代码输出*(a+1)和a[1]也就是一样的效果了,只不过*(a+1)是编译器分析处理后得出的结果*(a+1)而已,到这里我可以得出一个惊人的结论指针比数组要快[1],这样也就不难理解了,因为数据要通过编译器把数组的a[1]运算变成指针运算*(a+1),这一步是需要花时间的,而指针直接省了这一步,运算速度自然快,这个只是个人对于指针快于数组的理解,有什么理解误区的地方还望各读者指出一起进步。

附《狂人C》指针章节地址,有兴趣的朋友可以好好研究下:http://www.cnblogs.com/KBTiller/archive/2010/12/23/1914542.html

参考文献

[1]. H.M.Deitel、P.J.Deitel.C程序设计教程[M].北京:机械工业出版社.2007:218.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: