- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
编译原理视角下CC语言左值教学
编译原理视角下CC++语言左值教学
摘要:在C/C++语言的教学中,赋值语句通过赋值号“=”把左值和右值连接起来。能充当左值的语法单元是有限制的。如果学生不理解其中的限制条件往往会书写错误的赋值语句。本文从编译原理的值属性和地址属性出发分析左值的必要条件,学生通过简单地观察这些必要条件是否满足来判定一个赋值语句的左值是否合法,从而使赋值语句和左值的教学方法简明、到位。
关键词:C/C++;教学方法;左值;编译原理
中图分类号:G642.4 文献标志码:A 文章编号:1674-9324(2013)15-0068-02
在计算机课程体系中,C/C++语言是一门基础课程,它是许多计算机专业课程的先修课。在C/C++语言的教学中,赋值语句是最常见、最重要的语句了。学生在书写这类语句时经常会出现编译错误和运行错误,这些错误究其原因是学生对左值的概念没有明晰的理解,它其实是编译原理中的概念。在C/C++的教学中教师虽然不必对编译原理的有关内容进行讲解,但应当把左值的属性讲清楚,指出只有明确地址属性的单元才能作为赋值语句的左值。这样才能使学生彻底避免赋值语句的书写错误,才能使赋值语句的教学简明到位。
一、左值和赋值语句
C/C++的语句“a=b;”中的等号不同于数学中的等号,而是赋值号,数学中的等号具有对称性,表示等号左边和右边两个对象取值一样,将左右两个对象对调,不影响表达的意思,数学中的等式是静态的描述,是陈述句。而C/C++语言中的赋值号“=”没有对称性,表示把“=”右边的值赋给左边的对象,左右对象不能对调,对调了就破坏了原意,甚至引发编译致命错误(fatal error),赋值是动态过程,赋值语句是祈使句。所以有些语言干脆用LET或:=之类的符号表示赋值语句,以区分于数学里的等式。由于赋值语句的左右非对称性,就产生了左值和右值的概念,这其实是编译原理中的概念,在一个赋值语句中,被赋的对象叫赋值语句的左值(l-value),用于赋值的对象叫赋值语句的右值(r-value),它们分别出现在赋值号的左边和右边。C/C++语言的赋值语句的文法形式定义是:→=。左值必须由具有内存地址的变量、数组元素等充当。右值则广???得多,任何表达式都可以。一个赋值语句的语义动作是:先把右值的值算出来,赋到左值所指定的某个地址处的内存单元,并覆盖掉左值中原来的值。完整的赋值语句,只须右值能算出“值”来就行。但左值仅有“值”属性是不行的,必须有明确的内存地址属性。能充当左值的对象可充当右值,反之不一定。在C/C++中,除了简单变量名之外,数组元素、结构体变量的成员、共用体变量的成员通常情况下也都可以作为左值,原因就是这些对象都具备地址属性和明确的地址值,能把右值赋到这里。
二、案例分析
常量不能作为左值,语句“5=a;”错误,因为5只有值属性,而无地址属性,故不能作为左值。复杂表达式不能作为左值,如语句“a+b=5;”错误,赋值号左边的“a+b”不是编译符号,只有一个临时值,不存在地址属性。a++是赋值语句,相当于“a=a+1;”,a既是左值又是右值。所以不允许如下自加(自减)语句:3++;(a+b)--;++(a+3);数组名是常量,不能作为左值,若有short arr[10];arr表示一个短整型数组,它由10个元素组成,这10个元素顺序排列,其地址依此递增2字节,第i个元素用arr[i]或*(arr+i)表示,这些元素除了值属性外,还具备地址属性,可以作为左值,也就是说可以被赋值。数组名arr就不可以被赋值,因为一旦arr数组的空间分配了,arr作为首元素arr[0]的地址就确定了,是个常值,准确地说,arr是个地址常量,它只有值属性(只不过这个常值是个内存地址值),它本身没有地址属性。数组名作为函数的形式参数时,情况有点特殊。看代码段:
fun(int a[ ],int n)
{ while(n--)
{ printf(%d , *a);
a++;
}
}
a是数组名,但其中的赋值语句“a++;”合法。实际上,C/C++编译都是将形参数组名作为指针变量来处理的。上面给出的函数fun的形参a写成数组形式,但在编译时是将a按指针变量处理的,相当于fun函数的首行写成fun(int*a,int n),这样一来,语句“a++;”的合法性就有了,a在函数fun的实现代码中可以作为左值。对多维数组要小心,假设有二维数组char b[3][5];b、b[1]不能作为左值,b[1][3]或*(b[1]+3)才可以作为左值。原因是b表示该二维数组第0行b[0]的行地址,b[1]表示第1行第0列元素b[1][0]的地址,它们都是地址常量,有值属性,无地址属性,故不能作为左值。b[
文档评论(0)