以下程序中 & 和 && 运算符有什么用途?

4
我在一个网站上看到了下面的代码,用于检查奇偶数而不使用“if”。但是,我无法理解这个代码及其工作原理。请问您能否解释一下代码的功能部分。 代码如下:
#include<stdio.h>
#include<conio.h>
int main()
{
    int no;
    clrscr();
    printf("Enter a number");
    scanf("%d",&no);
    (no & 1 && printf("odd")) || printf("even");
    return 0;
    getch();
}

1
按位与 - devnull
3
printf 的输出应该能给你一个提示。 - Yu Hao
@alk 我的意思不是printf函数的返回值,我的意思是输出内容,即 "odd""even" - Yu Hao
哦!谢谢大家。我现在可以理解运算符的短路行为了。 - kalyan
@user3289137 你会注意到同一个符号可以用于不同的操作,例如 & 可以是取地址运算符或按位或运算符。这取决于它在哪种语法中出现,& 符号在语法 &a 中是取地址的一元运算符,在表达式 a & b 中是按位与的二元运算符。同样地,你也可以观察到 * 的差异。 - Grijesh Chauhan
8个回答

4
&用于按位与操作,&&用于逻辑与操作。
现在的逻辑是,如果一个数字的最低有效位为0,则它是偶数;如果最低有效位为1,则它是奇数。(no & 1)检查最低有效位是0还是1,即通过按位与运算,如果最低有效位是0,则结果为0,如果最低有效位是1,则结果为1
如果结果为0,则&&运算符的右表达式不会被执行,因为这个运算符有短路行为,所以左表达式的结果为"even"。如果(no & 1)的结果为1,则&&运算符的右表达式会被执行,并输出"odd"

4

no & 1可以得到no的最低位。因此,如果no是奇数,则no & 1等于1。

如果no & 1 == 0,则不执行逻辑运算符&&右侧的代码,(no & 1 && printf("odd"))返回假值,并执行printf("even")

如果no & 1 != 0,则执行逻辑运算符&&右侧的代码,并在控制台上打印"odd"。如果printf()成功执行,则(no & 1 && printf("odd"))返回真值,接着跳过逻辑运算符||右侧的代码。


3
  1. &no, address operator

    scanf("%d",&no);
    

    This &no means the address of the variable no. It is used to have scanf() put the result there.

  2. &, bitwise AND

    no & 1

    This is the value of no, bitwise ANDed with the value 1. Essentially, this gives the value of the lowest bit. If that bit is set, the value is odd, otherwise even.

  3. && and ||, short-circuit operators

    ((expression from above) && printf("odd")) || printf("even");
    

如果这个值是奇数,此表达式应该输出odd,如果这个值是偶数,则输出even

&&||被称为“短路运算符”。因此,以下情况会发生:

  • 如果表达式为false(== 0),第一部分计算为(0 && ...),它在不计算第二部分的情况下计算为0。因此我们有0 || printf("even"),这相当于printf("even")
  • 然而,如果表达式为true(!= 0),则第一部分计算为(1 && ...),其中1 &&是多余的。因此,实际上你有printf("odd") || printf("even")。这依赖于printf("odd")返回一个非零值,以便抑制printf("even")

因此,更好的解决方案是:

(no & 1) ? printf("odd") : printf("even");
printf((no & 1) ? "odd" : "even");
if (no & 1) {
    printf("odd");
} else {
    printf("even");
}

3
no & 1 是按位与运算,如果 no 是偶数,则结果为 0,如果 no 是奇数,则结果为 1。这是因为只有 1 的最低有效位被设置。 (no & 1 && printf("odd")) 中的 && 是布尔与运算,并且该表达式依赖于该运算符的短路求值。如果 no & 1 的结果为 false(当 no 是偶数时),则该语句将不会打印。当 no & 1 的结果为 true(当 no 是奇数时),则将评估 printf("odd") 语句。
只有在 no & 1 的结果为 false 的情况下,整个 && 表达式才会评估为 false,并且第二个 printf 语句将被评估。

2

所以你想理解的是(no & 1 && printf("odd")) || printf("even");

  • &表示按位与,因此no & 1表示从1获取第一位。
  • &&表示逻辑与,但它使用短路,如果第一个表达式为true,则不会评估第二个表达式。
  • ||表示逻辑或,但它使用短路,如果第一个表达式为false,则不会评估第二个表达式。

所以如果(no & 1) == 1,换句话说,如果no % 2 == 1,它将打印奇数;否则它将评估最后一个printf,因此将打印偶数


1

&& 是逻辑与。
true && true 为 true,其他情况均为 false。
& 是按位与。

可以用二进制来解释:

Code:
  00000110
& 00000100
----------------
  00000100
================

更多信息请参考:http://www.cprogramming.com/tutorial...operators.html 阅读其他位运算符。


1

取“no”中的第一个比特位,如果是0,则跳过&&运算符并继续评估printf("even")。 如果是1,则评估printf("odd")。


0

&no 是变量 no 的地址。 && 是逻辑与。 || 是或。


2
哦,不,应该是 no & 1,而不是 &no - Yu Hao
@YuHao 在上一行中我们也有一个&no - glglgl
@glglgl 哦,是的,我在脑海中自动跳过了那一行。 - Yu Hao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接