为什么有多个作品,如果不是这样的话

Why multiple if works and if else does not it this case

我正在学习 C,但遇到了一个奇怪的问题。我想我理解多个 ifs 和 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' 都可以很好地更新数组。

你能帮我理解这种情况下的行为差异吗?

我们需要知道的:

  • < 比较的结果是 int,值为 1 表示真,0 表示假。这就像 1 + 3 的结果是 int,值为 4,同样地,1 < 3 的结果是 int,值为 1
  • 运算符<具有从左到右的结合性。这意味着在 1 < 2 < 3 中它将被解析为 (1 < 2) < 3 - 即。首先会被1 < 2计算,然后结果会< 33相比较。

所以:

'A' < c < 'Z'

被解释为

('A' < c) < 'Z'

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

1 < 'Z' 

否则变成:

0 < 'Z'

两种情况都成立,所以比较总是成立的。

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

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

#include <ctype.h> and use isupper函数:

if (isupper(c)) {

<这样的关系运算符接受两个操作数,returns如果第一个操作数小于第二个则为1,否则为0。

因此 'A' < c 给出结果 1 或 0,然后(因为 < 运算符从左到右关联)您将值 1 或 0 与 'Z' 的 ASCII 值进行比较,这是胡说八道。

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

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

还要确保 cint 而不是 char,因为 getchar 实际上 returns int,并与 EOF 你将需要使用 int.

尝试

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

'a'<c<'z' 的计算不像数学表达式,首先 'a' < c 被评估为 TrueFalse 然后该值(可能转换为 0 或 1)是与 'z' 相比,它没有按照您的预期进行。