zoukankan      html  css  js  c++  java
  • 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;
    	}
    }
  • 相关阅读:
    antd4.0 踩坑记录
    使用movable-view制作可拖拽的微信小程序弹出层效果。
    Taro踩坑记录一: swiper组件pagestate定制,swiperChange中setState导致组件不能滚动。
    Failed to load resource: net::ERR_INSECURE_RESPONSE 问题解决记录
    Vue-cli中使用vConsole,以及设置JS连续点击控制vConsole按钮显隐功能实现
    dvajs+antd定制主题踩坑记录
    关于iosselectjs插件设置同步值的操作实践
    《你不知道的javascript》上卷笔记整理(一)
    三次面试总结以及今后的todolist
    前端Vue中常用rules校验规则
  • 原文地址:https://www.cnblogs.com/xuesu/p/4296971.html
Copyright © 2011-2022 走看看