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 问题描述 问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个表达式. 输出格式 输出这个表达式的 ...
随机推荐
- 2.wireshark分析之TCP协议(一)
(1) TCP是怎么样的协议? TCP是一种面向连接(连接导向)的.可靠的基于字节流的传输层通信协议.TCP将用户数据打包成报文段,它发送后启动一个定时器,另一端收到的数据进行确认.对失序的数据重新排 ...
- python基础之函数式编程、匿名函数、内置函数
一 函数式编程 不修改外部状态. 模仿数学里得函数进行编程. 用函数编程写出得代码相当精简. 可读性比较差. 例子: y=2*x+1 x=1 def test(x): return 2*x+1 tes ...
- form表单上传图片问题:线下可以而线上不可以
由于上传图片需要一定时间,而线下速度快线上速度慢. 所以如果你的上传窗口是弹出界面,那么就会面临上传未完成就关闭了该界面.导致上传失败.
- nodejs Async详解之三:集合操作
Async提供了很多针对集合的函数,可以简化我们对集合进行异步操作时的步骤.如下: forEach:对集合中每个元素进行异步操作 map:对集合中的每个元素通过异步操作得到另一个值,得到新的集合 fi ...
- Keras实践:模型可视化
Keras实践:模型可视化 安装Graphviz 官方网址为:http://www.graphviz.org/.我使用的是mac系统,所以我分享一下我使用时遇到的坑. Mac安装时在终端中执行: br ...
- http之响应报文response
一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息. HTTP响应也由四个部分组成,分别是:状态行.消息报头.空行和响应正文. http响应消息格式.jpg 例子 HTTP/ ...
- Spring—切点表达式
摘要: Spring中的AspectJ切点表达式函数 切点表达式函数就像我们的GPS导航软件.通过切点表达式函数,再配合通配符和逻辑运算符的灵活运用,我们能很好定位到我们需要织入增强的连接点上.经过上 ...
- AtCoder Beginner Contest 114 Solution
A 753 Solved. #include <bits/stdc++.h> using namespace std; ]; int main() { mp[] = mp[] = mp[] ...
- hdu 5185 动态规划 分析降低复杂度
这题说的是 x[1]+x[2]+x[3]+…+x[n]=n, 这里 0 <= x[i] <= n && 1 <= i <= n x[i] <= x[i+1 ...
- bzoj1612 / P2419 [USACO08JAN]牛大赛Cow Contest(Floyd)
P2419 [USACO08JAN]牛大赛Cow Contest Floyd不仅可以算最短路,还可以处理点之间的关系. 跑一遍Floyd,处理出每个点之间是否有直接或间接的关系. 如果某个点和其他$n ...