- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
c 数组与指针 2
?
c数组与指针(2)2010-04-05 11:40第四章[]运算符的本质数组是存在于人们头脑中的一个逻辑概念,而编译器其实并不知道有数组这个东西,它所知道的,只是运算符,当遇到运算符的时候,编译器只是简单地把它转换为类似*(*(a+i)+j)这样的等价表达式,之所以是这种表达式,如前几章所述,是因为C语言的数组实现本质上是数组的嵌套。由于这种等价关系的存在,会产生一些古零精怪的表达式,例如:10[a]这个表达式初看上去让人摸不着头脑,它是什么呢?如上所述,编译器会把它转换为*(10+a),把a和10调换一下,就是*(a+10)了,这个就是a[10]。运算符之前还可以是一个表达式,例如:(10+20)[a]。严格来讲,以上两个表达式是非法的,因为C89对于数组的引用(注意不是数组定义)规定:带下标的数组引用后缀表达式由一个后缀表达式后跟一个括在方括号中的表达式组成。方括号前的后缀表达式的类型必须为指向T类型的指针,其中T为某种类型;方括号中表达式的类型必须为整型。这个规定说明,进行数组引用的时候,运算符的左边并非必须为数组名,而可以是一个表达式,但这个表达式的类型必须为指向某类型的指针。显然10跟(10+20)连地址都不是,因此实际上他们是非法的,编译器在这里并没有严格遵守标准的规定。但如果是:int a[10],*p=a;(p+1)[2]这样就是合法的,因为p+1的结果仍然是一个指针。要注意的是,虽然后缀表达式是一个指向某类型的指针,但不要被这里所说的指针一词搞混了,上面的规定不能反过来使用。还是以上面的例子为例,我们可以p[i]这样使用p,这是符合上述规定的,但并不能因为指针p能够以p[i]这种形式使用就认为p是一个数组,这就错误了,不能反过来应用上述规则。最后说一下编译器对*的优化,对于数组int a[10],如果对其中一个元素取地址,例如a[1],这条表达式等价于*(a+1),编译器并不会先计算*再运算,而是对*两个运算符进行优化,把它们同时去掉,因为两者的作用是相反的,最后得到计算的是a+1表达式。第五章指向数组的指针讲到第五章了,数组两个字还离不开我们的左右,数组的内容也真多,另一方面也因为数组与指针的关系的确非常密切。通常,对于int a[8][9]这个二维数组,我们可以这样定义一个指向它的指针:int(*p)[9];这个声明的形式跟人们所熟悉的int*p的形式大相庭径,初学者通常会感到迷惑,不理解的地方大致有四个:1。为什么会以这种形式声明?2。(*p)应该如何理解?3。为什么必须把第二维显式地声明?4。为什么忽略第一维?下面我们就一起逐个讨论这四个问题:1。这种形式是C标准的声明语法规定的,由于本章不是对标准的解释,只是对标准的应用,因此笔者尽量以简洁的方式解释这个声明,详细的讨论将在第七章进行。C标准的声明包含了两部分:声明:声明说明符初始化声明符表opt(opt的意思是可选)在声明说明符里面有一项类型说明符,int就是这种类型说明符。而初始化声明符表里面的其中一种形式,就是:直接声明符[常量表达式opt](*p)[9]就是这种直接声明符加的形式。2。p左边的*在这里不是取值运算符,而是一个声明符,它指出p是一个指针。而()括号是不能去掉的,如果去掉了,由于运算符优先级比*高,p就会先跟结合,这样p就变成了一个指针数组,而不是指向数组的指针。题外话:*p还有一种用法,就是当*是取值运算符的时候,*p是一个左值,表示一个变量,为什么*p是一个变量呢?也许有人会说,因为int i,*p=i嘛,其实这是结果不是原因。严格来说,i只是一个变量名,不是变量,在编译器的符号表里面,变量名是一个符号地址,它所代表的地址值是它指向的那段内存单元的地址,真正叫变量的是那段内存单元,懂汇编的朋友能很容易地区分出来,在汇编里面,可以这样定义一个变量名:VARW DW 10,20 VARW就是一个变量名,它在汇编里面是一个地址,代表了10所在的内存单元这个变量。由于p被初始化为i,*p指向i所代表的那段内存单元,因此说*p是一个变量。把i称为变量是一种习惯上的统称。3。定义一个指针的时候,首先必须定出指针的类型,由于这是一个指向数组的指针,如果数组的元素的类型定下来了,那么这个指针的类型也就定下来了。前面说过,C语言的多维数组实质上是数组的嵌套,那么所指向数组的元素必定具有数组类型,也就是说,这个数组的元素是一个具有6个int元素的数组,因此,p定义的时候,必须指定第二维的上界,这样才能把p的类型定下来。4。有这种疑问的人已经犯了一个错误,没有分清楚什么是指针,什么是数组,以数组的思维模式来看待这个指针p。定义一个数组(非static)的时候,需要在栈中静态分配一块内存,那么就需要知道这块内存的大小,因此定义
文档评论(0)