摘要:

现行国内的C语言教材普遍不介绍序列点,这使得读者只能“死记硬背”有序列点表达式的求值顺序,不仅造成了读者对C语言知识的认知残缺不全,而且也影响了读者学习的积极性。本文总结了序列点的作用,即表达式求值时需考虑序列点的影响,序列点左边的操作数要先于其右边的操作数求值。结合操作符的作用,分析了逗号操作符,、逻辑与操作符&&、逻辑或操作符||和条件操作符?:的问号处?为什么会有序列点。

关键字:序列点 表达式 C语言

C语言是最重要的结构化程序设计语言,许多编程语言如Java、C++、C#都借鉴了C语言的语法。随着数字化信息技术的发展和网络环境的形成,计算机已渗透到各行各业,为了更好地了解和使用计算机,国内大专院校的许多理工类专业都开设了C语言课程,因此,C语言的教学水平影响着许许多多的学生。

现行国内的C语言教材通常不介绍序列点,这使得读者只能“死记硬背”有序列点表达式的求值顺序。以简单的逗号表达式为例,设变量a为整型变量(下文中出现的变量a也为整型变量),在分析表达式a = 3, ++a的求值顺序时强调“逗号表达式自左向右依次求值”,而在分析表达式求值的原则时强调根据操作符的优先级和结合性确定求值顺序。即使表达式中自增操作符++的优先级最高,也要先对子表达式a=3求值,该怎样向学生解释这与求值原则矛盾的“求值顺序”呢?

1序列点的定义及分析

根据C语言标准[1][2][3],序列点就是执行序列中的一些特定点,在这些点上,前面求值的副效应(side effect)应彻底完成且其后求值的副效应均未发生。在教材中照搬标准让初学者学习理解序列点这个概念是不明智的,应直接向初学者指出序列点在表达式求值中起的作用。C语言表达式求值的原则为:根据操作符的优先级和结合性确定表达式的求值顺序,但求值时要考虑序列点的影响,需保证序列点左边的操作数先于其右边的操作数求值。

2操作符的操作数

操作数是指操作符进行操作的操作对象,如表达式3+2中加法操作符左边的操作数为3,右边的操作数为2。在复杂的表达式中,需结合操作符的优先级和结合性来确定某操作符的操作数。对于表达式3+2*5,加法操作符左边的操作数为3,但其右边的操作数不为2,因为进行加法运算时3不可能和2相加,其右边的操作数为2*5(的积);而乘法操作符左边的操作数为2,右边的操作数为5。

表达式a = 0 && ++a中逻辑与左边的操作数为0,右边的操作数为子表达式++a,整个表达式为赋值表达式;而表达式(a = 0) && ++a中逻辑与左边的操作数为子表达式(a = 0),右边的操作数为子表达式++a,整个表达式为逻辑表达式。

3C语言中有序列点的操作符

逗号操作符,有序列点。逗号操作符的作用为把多条语句变成一条语句,如a = 2;和++a;为两条语句,而a = 2, ++a;是一条语句。语句a = 2, ++a;执行时,如果逗号操作符没有序列点,子表达式++a就会先执行,即这条语句的执行顺序与上面两条语句的并不相同。基于逗号操作符的作用,逗号操作符只能优先级最低,且含有序列点。

逻辑与操作符&&有序列点。C语言中逻辑与操作符会“短路计算”,即当其左边的操作数为假时,不对右边的操作数求值而直接把0(假)作为结果。表达式3>5 && ++a求值时,如果逻辑与操作符没有序列点,子表达式++a就会先执行,即逻辑与操作符的短路计算名存实亡。为了短路计算,逻辑与操作符&&需序列点。求值时需保证序列点左边的操作数要先于其右边的操作数求值,故表达式3>5 && ++a中逻辑与操作符左边的操作数先求值,即子表达式3>5先求值,结果为0,即假,由于短路计算,整个表达式的值为0,即假,且右操作数子表达式++a不会被求值。

逻辑或操作符||有序列点。C语言中逻辑或操作符也会“短路计算”,因此,其有序列点的必要性与逻辑与的相同。

条件操作符?:的问号处?有序列点。条件操作符用于改写简单的if-else选择结构,如下面的语句(设变量b为整型变量)

if(a > b)

++a;

else

++b;

可用条件操作符改写为a > b ? ++a : ++b;。

如果条件操作符没有序列点,语句a > b ? ++a : ++b;执行时,++a和++b会先于子表达式a > b执行,这样的执行顺序显然与if-else选择结构的不同,因此,条件操作符?:的问号处?有序列点。语句a > b ? ++a : ++b;执行时,问号处?左边的操作数a > b先执行,值为真时,对++a求值,不对++b求值;值为假时,正好相反。

4结束语

虽然C语言表达式种类繁多,但表达式求值时有着相对明确的求值规则,只要根据求值规则分析,再奇特的表达式也不会成为学习上的难点。表达式求值时需考虑序列点的影响,忽视它的存在就不能正确地分析C语言表达式的求值顺序,只能让学生“死记硬背”,影响学习积极性。在教材中直接引入序列点的概念势必会增加学习的难度,从序列点在表达式求值中的作用入手,给初学者提供一个容易理解的序列点概念,不仅不会造成C语言知识点的残缺,而且也为“启发式教学”提供了可能,如可以引导初学者分析操作符为什么要有序列点。

参考文献

[1] International Organization for Standardization. ISO/IEC 9899:1999.

[2] International Organization for Standardization. ISO/IEC 9899:1990.

[3]国家技术监督局. GB/T 15272-94 程序设计语言 C. 1994

[4]周二强. C语言内涵教程[M]. 中国铁道出版社 2013.

C语言序列点浅析的更多相关文章

  1. C语言序列点问题总结(大多数高等教育C语言教学课程的漏洞)

    C语言序列点总结 2013年11月21于浙大华家池 C 语言副作用: (side effect)是指对数据对象或者文件的修改. 例如,语句 v = 99;的副作用是把 v 的值修改成 99. C语言序 ...

  2. ReactiveX序列——RxSwift 浅析

      ReactiveX序列——RxSwift Swift是苹果公司新推出的一门现代化的编程语言,并且将其开源出来了,Swift具有很多的优点,这也使得这门语言推出的短时间引起了很大反应的原因,在最近的 ...

  3. C语言之goto浅析

    1.  读代码时遇了的疑惑点: static int do_bind(const char *host, int port, int protocol, int *family) { int fd; ...

  4. C语言 序列反向互补函数

    1 static char *revers(char *s) 2 { 3 int len=strlen(s); 4 char *s2=(char *)malloc(sizeof(char)*(len+ ...

  5. 10. Go 语言反射

    Go 语言反射 反射是指在程序运行期对程序本身进行访问和修改的能力.程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分.在运行程序时,程序无法获取自身的信息. 支持反射的语言可以在 ...

  6. MTU-TCP/IP协议栈-linux kernel-TCP丢包重传-UDP高性能-AI-

    http://view.inews.qq.com/a/20161025A0766200窄带时代的QQQQ是窄带时代极具代表性的产品,在那个网络传输效率比较低的年代,大家还记得Google的首页吗?Go ...

  7. python的编码问题研究------使用scrapy体验

    python转码译码 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impo ...

  8. [转]语言模型训练工具SRILM

    SRILM是一个建立和使用统计语言模型的开源工具包,从1995年开始由SRI 口语技术与研究实验室(SRI Speech Technology and Research Laboratory)开发,现 ...

  9. 【OCR技术系列之五】自然场景文本检测技术综述(CTPN, SegLink, EAST)

    文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别.今天我们首先来谈一下当今流行的文字检测技术有哪些. 文本检测不是一件简 ...

随机推荐

  1. Oracle 11g 客户端的安装和配置。

    原文:Oracle 11g 客户端的安装和配置. 数据库和客户端在不同的机器之上. 在安装之前,在安装Oracle数据库的服务器上导航到下面的目录. 将listener.ora和tnsnames.or ...

  2. Floodlight 在 ChannelPipeline 图

    我们知道,在Netty架构,一个ServerBootstrap用于生成server端的Channel的时候都须要提供一个ChannelPipelineFactory类型的參数,用于服务于建立连接的Ch ...

  3. jekyll bootstrap搭建github blog

    前提你必须有一个GitHub账号且本机安装有Git 一.创建一个新的仓库 去你的https://github.com主页新建一个仓库 名字为USERNAME.github.com USERNAME为你 ...

  4. 【转】webAPP快速入门

    WebApp与Native App有何区别呢? Native App: 1.开发成本非常大.一般使用的开发语言为JAVA.C++.Objective-C. 2.更新体验较差.同时也比较麻烦.每一次发布 ...

  5. php中session和cookie

    cookie 每次请求页面的时候进行验证,如果用户信息存储在数据库中,每次都要执行一次数据库查询,给数据库造成多余的负担.cookie可以被修改的,所以安全系数太低. session是存储在服务器端面 ...

  6. 反射导出excel案例

    1.代码案例: protected void btnExportExcel_Click(object sender, EventArgs e) { SetSearchValue(); Dictiona ...

  7. Cocos2d-x 3.1.1开发环境

    Windows7上搭建Cocos2d-x 3.1.1开发环境   前言 现在,越来越多的公司采用Cocos2d-x 3.0来开发游戏了,但是现在这样的文章并不多,所以打算写一系列来帮助初学者快速掌握C ...

  8. Asp.Net Web Api 接口

    如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问.   由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的 ...

  9. 利用自定义的AuthenticationFilter实现Basic认证

    [ASP.NET MVC] 利用自定义的AuthenticationFilter实现Basic认证   很多情况下目标Action方法都要求在一个安全上下文中被执行,这里所谓的安全上下文主要指的是当前 ...

  10. ASP.NET MVC显示WebForm网页或UserControl控件

    ASP.NET MVC显示WebForm网页或UserControl控件 学习与使用ASP.NET MVC这样久,还是对asp.net念念不忘.能否在asp.net mvc去显示aspx或是user ...