【问题标题】:Why multiple if works and if else does not it this case [duplicate]为什么多个 if 有效,而 if else 在这种情况下无效 [重复]
【发布时间】:2019-12-15 21:56:12
【问题描述】:

我正在学习 C,但遇到了一个奇怪的问题。我想我理解了多个 if 和 else-if 语句之间的区别,但我根本无法理解这次行为上的区别。如果我删除 else 关键字,它会按预期工作,但如果加上 else 则不会。

代码是关于在不区分大小写的情况下计算每个字母的出现次数(因此“a”和“A”都算作字母“a”出现 1 次)。

我已经尝试在可能的情况下省略大括号,但没有任何改变,所以我将它们留在里面以避免警告。

while ((c = getchar()) != EOF)
{
if ('A' < c < 'Z')
    {
        ++array[c - 'A'];
    }
    else if ('a' < c < 'z')
    {
        ++array[c - 'a'];
    }
}

当我输入“a”时,数组不会递增,但如果我删除 else 语句从而切换到多重 if 情况,它会按预期工作。字母“A”在这两种情况下都很好地更新了数组。

能否请您帮助我理解在这种情况下的行为差异?

【问题讨论】:

  • if ('A' &lt; c &lt; 'Z')做你认为它做的事。使用if ('A' &lt; c &amp;&amp; c &lt; 'Z')(顺便说一句,它排除“A”和“Z”从允许值的域中;考虑到典型白话中的字母“A”)。
  • 这是一个常见的初学者错误,源于假设该语言以某种方式工作,而不是研究它实际上是如何工作的。你不能通过反复试验来编写代码。
  • 您将c 定义为int,对吗?如果您定义为char,则会出错。
  • 好吧,至少安蒂找到了一个像样的规范骗子。我添加到 SO C 常见问题解答 here,因为这是一个常见的初学者问题。
  • 奇怪的是 if ('A' &lt; c &lt; 'Z') 为字母 'A' 工作。你的假设是对的,但我仍处于这本书的开头,并开始为事情增添一些趣味。是的,c 是整数。感谢您链接常见问题解答,我将确保仔细阅读。

标签: c if-statement codeblocks


【解决方案1】:

我们需要知道的:

  • &lt; 比较的结果是int1 为真,0 为假。就像1 + 3 的结果是int 的值为4,同样1 &lt; 3 的结果是int 的值为1
  • 运算符&lt; 具有从左到右的关联性。这意味着在1 &lt; 2 &lt; 3 中,它将被解析为(1 &lt; 2) &lt; 3 - 即。首先将计算1 &lt; 2,然后将&lt; 33 进行比较。

所以:

'A' < c < 'Z'

被解释为

('A' < c) < 'Z'

'A' &lt; c 的结果是 10。当'A' 低于c 时,则变为:

1 < 'Z' 

否则会变成:

0 < 'Z'

两种情况都为真,所以比较总是为真。

如果你想检查一个数字是否是AZ之间的字母包括字母AZ,你可以:

if ('A' <= c && c <= 'Z') {

#include &lt;ctype.h&gt; 并使用isupper 函数:

if (isupper(c)) {

【讨论】:

  • 请记住,isupper/islower 使用当前语言环境,因此它们可能不一定与检查字母是否在 A 和 Z 之间相同。
  • OP 注释。假设在运行此代码时所需的语言环境在起作用,后者特别值得考虑,因为假设'A'...'Z'doesn't necessarily hold water 的不间断连续性。在这种情况下,比较不是伤害的世界。 array 索引但是...哎哟。
【解决方案2】:

试试

while ((c = getchar()) != EOF)
{
if ('A'  <= c && c <= 'Z')
    {
        ++array[c - 'A'];
    }
else if ('a' <= c && c <= 'z')
    {
        ++array[c - 'a'];
    }
}

'a'&lt;c&lt;'z' 的计算不像数学表达式,首先 'a' &lt; c 被评估为 TrueFalse 然后该值(可能转换为 0 或 1)与“z”进行比较,所以它不是做你所期望的。

【讨论】:

    【解决方案3】:

    &lt; 等关系运算符接受两个操作数,如果第一个操作数小于第二个操作数,则返回 1,否则返回 0。

    因此'A' &lt; c 给出的结果为 1 或 0,然后(因为 'Z' 的 ASCII 值进行比较,这是无稽之谈。

    检查变量是否在区间内的正确代码是

    if ( (c >= 'A') && (c <= 'Z') )
    

    还要确保cint 而不是char,因为getchar 实际上返回int,并且要与EOF 进行比较,您将需要使用int

    【讨论】:

      猜你喜欢
      • 2019-12-11
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多