为了账号安全,请及时绑定邮箱和手机立即绑定

为什么一个变量与许多值的不相等检查总是返回true?

为什么一个变量与许多值的不相等检查总是返回true?

为什么一个变量与许多值的不相等检查总是返回true?我有一个变量v在我的节目里,它可能需要任何值集合中的值。"a", "b", "c", ..., "z"我的目标是只在以下情况下执行一些语句v不是"x", "y",或"z".我试过了对于类C语言(其中相等运算符比较实际字符串值C#, JavaScript, PHP)if (v != "x" || v != "y" || v != "z"){     // the statements I want to be executed     // if v is neither "x", nor "y", nor "z"}用于类似PASCAL的语言(例如:plsql)IF (v != 'x' OR v != 'y' OR v != 'z') THEN     -- the statements I want to be executed     -- if v is neither "x", nor "y", nor "z"END IF;if条件内的语句总是被执行..我做错什么了吗?
查看完整描述

3 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

使用&&/AND/and,不是||/OR/or:

v != "x" && v != "y" && v != "z"

问题

如果if块,则为if块的条件。总是评估为true..逻辑表达式一定是错的。

让我们考虑一下v != "x" || v != "y" || v != "z"的每一个值v.

  • 什么时候v = "x",

    v != "x""x" != "x",也就是假的
    v != "y""x" != "y",也就是千真万确
    v != "z""x" != "y",也就是千真万确.

    表达式的计算结果为false || true || true,也就是千真万确.

  • 什么时候v = "y",表达式变成

    "y" != "x" || "y" != "y" || "y" != "z"

    true || false || true,也就是千真万确.

  • 什么时候v = "z",表达式变成

    "z" != "x" || "z" != "y" || "z" != "z"

    true || true || false,也就是千真万确.

  • 的任何其他价值v,表达式的计算结果为true || true || true,也就是千真万确.

或者,考虑一下真值表:

       │     A          B          C      │
  v    │  v != "x"   v != "y"   v != "z"  │  A || B || C
───────┼──────────────────────────────────┼──────────────
 "x"   │    false      true       true    │     true
 "y"   │    true       false      true    │     true
 "z"   │    true       true       false   │     true
other  │    true       true       true    │     true

如您所见,您的逻辑表达式评估为true.

您要做的是,找到一个计算为true什么时候

(v is not "x")and(v is not "y")and(v is not "z").

正确的结构是,

  • 用于C类语言(如。C#, JavaScript-(可能需要严格的相等操作符!==), PHP)

    if (v != "x" && v != "y" && v != "z"){
        // the statements I want to be executed
        // if v is neither "x", nor "y", nor "z"}
  • 类帕斯卡语言plsql

    IF (v != 'x' AND v != 'y' AND v != 'z') THEN
        -- the statements I want to be executed
        -- if v is neither "x", nor "y", nor "z"END IF;

德摩根定律

通过德摩根定律,表达式也可以重写为(使用C语法)

!(v == "x" || v == "y" || v == "z")

意义

not((v is "x")or(v is "y")or(v is "z")).

这使得逻辑更加明显。

特定语言

有些语言有特定的结构来测试集合中的成员资格,或者可以使用数组/列表操作。

  • SQL: v NOT IN ('x', 'y', 'z')

  • JavaScript: ["x", "y", "z"].indexOf(v) == -1

  • Python: v not in {"x", "y", "z"}

  • 爪哇: Arrays.asList("x", "y", "z").contains(v)

  • 爪哇-9(及以上):Set.of("x", "y", "z").contains(v)


查看完整回答
反对 回复 2019-06-03
?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

我想我会为Bourneshell脚本提供一个答案,因为语法有点奇怪。

传统/POSIXsh字符串相等测试是[命令(是的,这是一个不同的命令名!)在报价等方面有一些令人讨厌的要求。

#### WRONG
if [ "$v" != 'x' ] || [ "$v" != 'y'] || [ "$v" != 'z' ]; then
    : some code which should happen when $v is not 'x' or 'y' or 'z'
fi

现代贝壳如Ksh,Bash,Zsh等也有[[有点不那么烦人。

#### STILL WRONG
if [[ $v != 'x' || $v != 'y' || $v != 'z' ]]; then
    :  some code which should happen when $v is not 'x' or 'y' or 'z'
fi

我们应该强调在每个令牌周围有空格的要求,这是许多初学者忽略的事情(也就是说,您不能说if[[$v$v!='y'在命令和运算符周围没有空格),以及表观引用的可选性。不引用值通常不是句法错误,但它会导致严重的不期望。语义化如果你没有引用一个需要被引用的价值,那就麻烦了。

这里最明显的解决办法是使用&&而不是||但你也应该注意到[[通常对正则表达式的运动支持,所以您可以这样说

if [[ ! $v =~ ^(x|y|z)$ ]]; then
    : yeah
fi

别忘了那个可靠的老人case这是非常自然的说法,并可移植到1970年代后期:

case $v in
    x | y | z)
       ;; # don't actually do anything in this switch
    *) # anything else, we fall through to this switch
       yeah
       some more yeah
       in fact, lots of yeah;;
 esac

拖着的双分号起初会导致动脉瘤,但你很快就会恢复,学会欣赏,甚至喜欢它们。POSIX允许在匹配表达式之前放置一个括号,这样就没有未配对的右括号,但这种用法并不常见。



查看完整回答
反对 回复 2019-06-03
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

对于PHP,您可以使用这样的东西:


if(strpos('xyz',$v[0])===false)//example 1

//strpos returns false when the letter isn't in the string

//returns the position (0 based) of the substring

//we must use a strict comparison to see if it isn't in the substring


if(!in_array($v[0],array('x','y','z')))//example 2


//example 3

$out=array('x'=>1,'y'=>1,'z'=>1); //create an array

if(!$out[$v[0]]) //check if it's not 1


if(!preg_match('/^[xyz]$/',$v))//example 4, using regex


if(str_replace(array('x','y','z'),'',$v[0]))//example 5



if(trim($v[0],'xyz'))//example 6

对于Javascript:


if(~'xyz'.search(v[0]))//example 1(.indexOf() works too)


if(!(v[0] in {x:0,y:0,z:0}))//example 2


if(~['x','y','z'].indexOf(v[0]))//example 3, incompatible with older browsers.


if(!/^[xyz]$/.match(v))//example 4


if(v.replace(/^[xyz]$/))//example 5

对于MySQL:


Select not locate(@v,'xyz'); -- example 1


select @v not in ('x','y','z'); -- example 2


-- repetition of the same pattern for the others

C组:


if(!strstr('xyz',v))//example 1, untested

有更多的方法,我就是太懒了。


发挥你的想象力,只需写出你更喜欢的!


查看完整回答
反对 回复 2019-06-03
  • 3 回答
  • 0 关注
  • 688 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信