C语言对表达式的求值顺序不是明确规定的
讨论区看到的
WA来自那些递归下降求解的代码.
第一种情况,使用|| 和 &&:
例如s为所给串
int getval()
{
switch(s[c_s++])
{
case 'p': return (value & (1 << 0))? 1:0;
case 'q': return (value & (1 << 1))? 1:0;
case 'r': return (value & (1 << 2))? 1:0;
case 's': return (value & (1 << 3))? 1:0;
case 't': return (value & (1 << 4))? 1:0; case 'K': return getval() && getval();
case 'A': return getval() || getval();
case 'N': return !getval();
case 'C': return !getval() || getval();
case 'E': return getval() == getval();
}
}
这种情况简单,大家知道短路求值吧,先对 ||左边的表达式求值,如果非0,则不会对右边的表达式求值,&&同理,如果左边为0,不会对右边求值,这样下标就不会按照事先设想的增加
第二种情况,使用&和|:
int getval()
{
switch(s[c_s++])
{
case 'p': return (value & (1 << 0))? 1:0;
case 'q': return (value & (1 << 1))? 1:0;
case 'r': return (value & (1 << 2))? 1:0;
case 's': return (value & (1 << 3))? 1:0;
case 't': return (value & (1 << 4))? 1:0; case 'K': return getval() & getval();
case 'A': return getval() | getval();
case 'N': return !getval();
case 'C': return !getval() | getval();
case 'E': return getval() == getval();
}
}
首先这段代码用G++会AC,C++会WA,说明此段代码依赖编译器,是未定义的代码
错误原因: C语言对表达式的求值顺序不是明确规定的,而G++是从左从左向右求值,C++则正好相反,比如: getval() | getval() G++先对左边的getval()求值,而C++则先对右边的getval()求值,也就会导致对s的访问顺序不会按预先的步骤进行,所以用G++会ac,C++会WA掉
正确的写法,去掉那些跟依赖求值顺序的代码(好习惯),分别求值,用两个临时变量保存,这样G++和C++都AC了:
int getval()
{ int temp1, temp2;
switch(s[c_s++])
{
case 'p': return (value & (1 << 0))? 1:0;
case 'q': return (value & (1 << 1))? 1:0;
case 'r': return (value & (1 << 2))? 1:0;
case 's': return (value & (1 << 3))? 1:0;
case 't': return (value & (1 << 4))? 1:0; case 'K': temp1 = getval(); temp2 = getval(); return temp1 & temp2;
case 'A': temp1 = getval(); temp2 = getval(); return temp1 | temp2;
case 'N': return !getval();
case 'C': temp1 = !getval(); temp2 = getval(); return temp1 | temp2;
case 'E': temp1 = getval(); temp2 = getval(); return temp1 == temp2;
}
}
C语言对表达式的求值顺序不是明确规定的的更多相关文章
- 【部分原创】标准C语言的优先级、结合性、求值顺序、未定义行为和非确定行为浅析
零. 优先级 在C++ Primer一书中,对于运算符的优先级是这样描述的: Precedence specifies how the operands are grouped. It ...
- ZT C,C++表达式求值顺序 裘老的解释。 [问题点数:300分]
http://bbs.csdn.net/topics/370153775 [置顶] [推荐] C,C++表达式求值顺序 裘老的解释. [问题点数:300分] 最近这问题有从日经变时经的趋势,这里贴出裘 ...
- C++求值顺序
<C++Primer5th>中文版第124页 C++语言没有明确规定大多数二元运算符的求值顺序, 给编译器优化留下了余地. 这种策略实际上是在代码生成效率和程序潜在缺陷之间进行了权衡,这个 ...
- 诡异的C语言实参求值顺序
学了这么久的C语言,竟然第一次碰到这么诡异的实参求值顺序问题,大跌眼镜.果然阅读面太少了! #include<iostream> void foo(int a, int b, int c) ...
- &&、||、?:、,四个运算符的求值顺序
C语言中只有四个运算符(&&.||.?:.,)存在规定的求值顺序. 运算符&&和运算符||首先对左侧操作数求值,只在需要时才对右侧操作数求值. 运算符?:有三个操作数: ...
- SQL AND和OR求值顺序
假如需要列出价格为10美元及以上,且由DLL01或BRS01制造的所有产品.下面的SELECT语句使用组合的AND和OR操作符建立了一个WHERE子句: ; 分析▼ 请看上面的结果.返回的行中有4行价 ...
- C 语言 - 逻辑运算和短路求值
逻辑运算符: 运算符 含义 优先级 ! 逻辑非 高 && 逻辑与 中 || 逻辑或 低 举例: !a:如果 a 为真,!a 为假:如果 a 为 假,!a 为真 a && ...
- C++ 中缀转后缀表达式并求值
//中缀转后缀 #include<iostream> #include<stack> using namespace std; int prio(char x){ ; ; ; ...
- 算法笔记_044:表达式计算求值(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个表达式. 输出格式 输出这个表达式的 ...
随机推荐
- elasticsearch-hadoop使用
elasticsearch-hadoop是一个深度集成Hadoop和ElasticSearch的项目,也是ES官方来维护的一个子项目,通过实现Hadoop和ES之间的输入输出,可以在Hadoop里面对 ...
- HDU2426:Interesting Housing Problem(还没过,貌似入门题)
#include <iostream> #include <queue> #include <stdio.h> #include <string.h> ...
- Web安全大揭秘
web安全大揭秘,通常会有那些web安全问题呢? 1,xss 2,sql注入 3,ddos攻击
- 001-mybatis框架
架构分析: 1. 读SqlMapConfig.xml. 当调用与数据库有关的操作的时候,会读SqlMapConfig.xml文件中的信息,里面配置了Mybatis的运行环境信息,加载mapper.xm ...
- open-falcon设置报警邮件
下载编译好的二进制包并解压: https://files.cnblogs.com/files/dylan-wu/mail-provider.tar.gz [root@localhost work]# ...
- python实现指定目录下批量文件的单词计数:并发版本
在 文章 <python实现指定目录下批量文件的单词计数:串行版本>中, 总体思路是: A. 一次性获取指定目录下的所有符合条件的文件 -> B. 一次性获取所有文件的所有文件行 - ...
- Python: 矩阵与线性代数运算
需要执行矩阵和线性代数运算,比如矩阵乘法.寻找行列式.求解线性方程组等等. 矩阵类似于3.9 小节中数组对象,但是遵循线性代数的计算规则.下面的一个例子展示了矩阵的一些基本特性: >>&g ...
- react 项目微信端 签名失败 原因
用SPA做微信h5,调用微信jssdk的页面,安卓微信上木有问题,ios微信报当前url未注册 经过调试,是ios微信版本问题导致页面跳转url未变化,导致验签失败 所以我们大致的思想就是:在ios微 ...
- 裸眼3D全攻略3:拍摄3D—瞳距、镜距、视角偏转与空间感
http://sd89.blog.163.com/blog/static/356041322014112532958728/ 3D图片的拍摄,与平面有着全新的不同要求,那就是空间感的表现. 简单来说, ...
- git-format-patch如何指定补丁生成的Subject格式
答:使用-N来指定,如: git format-patch -N <commit-id> 生成的补丁中Subject将以[PATCH]的格式呈现,例如:Subject: [PATCH] a ...