IF和ELSE IF条款有什么区别?

时间:2015-09-21 09:16:00

标签: c

我正在与K& R学习C的道路上。除了书中的练习外,我自己也做了一些。我编写了以下代码,它的作用是,它会对您的输入进行计数,并为您提供反馈,以便为达到"目标" 10个单词,并在你达到10个单词时祝贺你。

#include <stdio.h>

main()
{
    /* This programm will read your input, check the number of words,
    and will congratulate when you reach a value of 10 words*/

    int c, nw, counter;

    nw = 0;
    counter = 0;

    while (nw < 10)
    {
        c = getchar();

        if (c == ' ' || c == '\t' || c == '\n')
        {
            counter = 0;
        }

        else if (c != ' ' || c != '\t' || c != '\n')
        {
            if (counter == 0)
            {
                counter = 1;
                ++nw;
            }
            printf("Only %d words left\n", 10-nw );
        }
    }
}

好的,在这个版本中,代码不会将空白计为单词,从而导致正确输出单词。

起初我只用&#34来编写代码;如果&#34;而不是&#34;否则如果&#34;。它所做的是它还将空白视为单词。

我问的问题是为什么?使用if或者if if的区别是什么。

据我所知,该编译器将检查是否满足条件。仅使用if时也应如此。因为一切都是期望的,如果不是,我无法弄清问题是什么。

4 个答案:

答案 0 :(得分:4)

不确定这是否是您正在寻找的答案。但无论如何,都会评估两个单独的 if 语句。使用&#34; 如果&#34;和&#34; 其他如果&#34;,如果评估,如果为真,则如果则跳过。当&#34; 如果&#34;不是真的&#34; 否则,如果&#34;被评估。

答案 1 :(得分:4)

看起来这可能是一个过度思考问题的案例。除了错误之外,你最终得到的逻辑过于复杂。您对ifelse if之间区别的问题是公平的,我保证会在答案中解决这个问题。

首先,让我重申你想要做的事情:

  

阅读输入,计算单词数量,并在达到10个单词时祝贺您

从您的代码中,我相信您的意图是根据空格,制表符和换行符拆分单词。有很多方法可以分割单词,但就本问题而言,您的预期方法很好。

问题当然是你的逻辑不起作用。你的条件永远不会是假的:

else if (c != ' ' || c != '\t' || c != '\n')

考虑一下(提示:else不会改变条件本身)。如果有帮助,请大声说出:您正在寻找c不是空格,或c不是标签,或c不是&#39; ta newline。请记住,逻辑或(||)是包含,换句话说,如果任何条件为true,则表达式为true c 1}}。例如,假设c != ' '是一个空格。第一个条件(c != '\t')失败,但第二个条件truetrue,因为空格不是标签。因此,整个表达式为c。实际上,对于 else的任何值,该表达式都是正确的。

但是else呢?

正如我所说,else if的{​​{1}}部分在这里没有任何区别。 else if唯一不同的做法就是将自己作为if语句的新条件。让我们看一个更简单的例子:

if (a == 1) {
    /* a is 1 */
}

if (a != 1 && b == 2) {
    /* a isn't 1, but b == 2 */
}

这是两个完全独立的if语句的示例。它是使用else的完美示例,因为您可能已经注意到,第二个if语句测试第一个的倒数。 (a != 1)。因此,上述内容可以简化如下:

if (a == 1) {
    /* a is 1 */
else if (b == 2) {
    /* a isn't 1 and b is 2 */
}

else if区块中,我们无需对a != 1进行测试,因为我们只考虑else语句,如果第一个if条件是假的。

另请注意,else if实际上是两个单独关键字的组合。它相当于:

else {
    if (b == 2) { ... }
}

但是,按照惯例,我们省略了可选的大括号并将其写为:

else if (b == 2) { ... }

事实上,在某些情况下,我们根本不需要第二个if

if (a == 1) {
    printf("a is 1!\n");
} else {
    printf("a isn't 1. In fact, it's %d.\n", a);
}

简化版

所以,现在没有必要陷入else if。专注于您的逻辑,并尽力简化它。我会为你简化它,但我鼓励你跳过这一部分,先自己尝试一下:

char c;
int in_word = 0;

while (nw < 10) {
    c = getchar();

    if (c == ' ' || c == '\t' || c == '\n') {
        /* If we were in a word, then count that word! */
        if (in_word) {
            nw++;
            printf("You only have %d words to go!", 10 - nw);
        }
        in_word = 0; /* We are not in a word now */
    } else {
        in_word = 1; /* Now we're in a word
    }
}

答案 2 :(得分:2)

else if (c != ' ' || c != '\t' || c != '\n')

这行代码可能没有按照你的意图行事。它作为else if工作正常,但事实上它并没有真正检查任何东西(你实际上可以用简单的else替换它)!对于任何可以想象的角色,它总是要么不是空格,要么不是制表符,或者不是换行符。你真正想要的是这些陈述的结合,而不是当前的分离:

else if (c != ' ' && c != '\t' && c != '\n')

这将检查字符既不是空格,也不是制表符,也不是换行符。即使将else删除,它也可以作为单独的if语句使用。但是,你真的应该选择一个简单的else

答案 3 :(得分:0)

if条件下,如果您使用简单的if .. else构造,则它将等同于

    if (c == ' ' || c == '\t' || c == '\n')
    {
        ...
    }
    else if (c != ' ' && c != '\t' && c != '\n') //Notice &&.
                        //Apply De-morgan's law over if conditio.
    {
      ...
    }

在上述情况下,else if不是必需的,if else就足够了。使用if .. else比给定代码更有效。

但是,从逻辑上讲,它可能与您给定的代码具有相同的效果。

根据逻辑,else if不是必需的。

如下所述,您将获得比较操作数量的差异。

当前代码:

  1. 对于任何非空格字符,例如'a',它将执行4次比较(||&&被短路。)
  2. 对于任何空格字符,最多可进行3次比较。
  3. if-else代码中,将执行最多3次比较。

    这种差异并不那么显着。并且只有在代码运行数十亿次时才能注意到。

    if else具有维护的额外优势。在OP中的上述代码中,如果if部分中有任何更改,则应将其反映在{{1}中部分也是。

    因此,对我来说,仅使用else if代替if else似乎是有益的。