为什么多重如果有效,如果不是这样的话

-3 c if-statement codeblocks

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

该代码是关于在不区分大小写的情况下对每个字母的出现进行计数的(因此,“ a”和“ A”都被视为字母“ a”的出现次数)。

我尽力去掉括号,但什么也没改变,所以我把它们留在里面以避免警告。

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

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

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

Kam*_*Cuk 5

我们需要知道的是:

  • The result of < comparison is an int with value 1 for true and 0 for false. It's like the result of 1 + 3 is int with value 4, the same way the result of 1 < 3 is an int with value 1.
  • Operator < has associativity Left to Right. That means that in 1 < 2 < 3 it will be parsed as (1 < 2) < 3 - ie. first will be 1 < 2 calculated, then the result will be < 3 compared with 3.

So:

'A' < c < 'Z'
Run Code Online (Sandbox Code Playgroud)

is interpreted as

('A' < c) < 'Z'
Run Code Online (Sandbox Code Playgroud)

The result of 'A' < c is either 1 or 0. When 'A' is lower then c, then it becomes:

1 < 'Z' 
Run Code Online (Sandbox Code Playgroud)

otherwise it becomes:

0 < 'Z'
Run Code Online (Sandbox Code Playgroud)

Both cases are true, so the comparison is always true.

If you want to check if a number is a letter between A and Z including the letters A and Z, you can:

if ('A' <= c && c <= 'Z') {
Run Code Online (Sandbox Code Playgroud)

or #include <ctype.h> and use isupper function:

if (isupper(c)) {
Run Code Online (Sandbox Code Playgroud)