C 位算术:我在 C 中使用 (number&1) == 0 来确定偶数或奇数 - 所有输入仅返回奇数

C Bit Arithmetic:I'm using (number&1) == 0 to determine even or odd in C - returns only Odd for all inputs

提问人:x iLeon 提问时间:6/5/2020 最后编辑:x iLeon 更新时间:6/5/2020 访问量:72

问:

我可以在很多方面确定一个数字是偶数还是奇数。我在这里的目的不是那个 - 而是测试一个特定的按位操作。下面是小代码:

#include <stdio.h>

int main(){
            unsigned int c;

            while(c=getchar()!='\n')
                    (c&1)==0?printf("Even"):printf("Odd");
            printf("\n");
}

我在终端上的输入是手动的,类型为:“1234567890”或“asdf5678”,总是以 \n 关闭,这就是为什么我不需要考虑 EOF。

我得到的输出基本上是“OddOdd...”的字符串,正如预期的那样,其数量与键入的字符数完全对应,但仅返回所有字符的“Odd”。

我是否错过了一些非常基本的东西?如前所述,我对解决一般问题不感兴趣 - 我有兴趣找出为什么这段特定的代码在逻辑合理的情况下不起作用。这与评估顺序有关吗?(从左到右等)我看不出这是运算符优先级的问题,因为我将 & 操作括在括号中,取代了 == 的优先级

C 操作 赋值- 按位 运算符

评论

7赞 user3386109 6/5/2020
错误在语句中。 具有高于赋值的优先级。基本上代码说,只要不等于 1while!=cgetchar()'\n'
2赞 paulsm4 6/5/2020
“我看不出这是操作员优先级的问题”——啊,但它是;)请参阅其他回复。“只是不想全部输入,让它太乏味而无法阅读)”错了!我强烈建议括号可以使代码的意图更易于阅读。我坚决反对“字符越少越好”的概念......
1赞 user3386109 6/5/2020
@xiLeon 您发布的代码中的主要问题是作业周围缺少括号。您必须有这些括号。否则,比较是第一位的,赋值根据比较结果给出值 0 或 1。查看代码中其他小问题的答案。c
0赞 x iLeon 6/5/2020
@user3386109 - 你是绝对正确的 - 我以为我已经尝试了那个替代方案(赋值周围的括号),但也许我没有同时尝试两个操作(赋值和按位运算)周围的括号!道歉
0赞 user3386109 6/5/2020
@xiLeon 每个人在学习时都会发生:一次转动太多旋钮,却找不到合适的组合:)

答:

3赞 Vlad from Moscow 6/5/2020 #1

while 语句中的表达式

while(c=getchar()!='\n')

相当于

while( c = ( getchar() != '\n' ) )

由于表达式总是屈服,除非按下 Enter 键,否则在循环的主体中输出字符串文字。getchar() != '\n'1"Odd"

你需要

while( ( c = getchar() ) != '\n' )

无论如何,最好写

int c;

while( ( c = getchar() ) != EOF && c != '\n' )

另外,在我看来,写起来会更易读

printf( "%s ", (c&1) == 0 ? "Even" : "Odd" );

而不是

(c&1)==0?printf("Even"):printf("Odd");
3赞 Thomas Jager 6/5/2020 #2

您遇到的问题在以下行:

while (c = getchar() != '\n')

并且是由于操作员优先级。具体而言,运算符的优先级高于 。添加括号可显示实际发生的情况:!==

while (c = (getchar() != '\n'))

条件将为 1,这是奇数,只要 的结果不是 。getchar'\n'

要解决此问题,请添加括号以正确分组操作:

while ((c = getchar()) != '\n')

然而,这忽略了失败时返回的事实。如果是 EOF,这将永远循环,等待永远不会到来的换行符。变量应至少为 ,而不是 ,以匹配 的返回类型。getcharEOFstdincintunsigned intgetchar

评论

0赞 x iLeon 6/5/2020
非常有帮助为我分解任务。谢谢!
0赞 x iLeon 6/5/2020
是的,未签名的出现是我试图修复代码(我对这一切有点陌生......我认为它可能不起作用,因为与符号位有关,当然,现在我已经看到了问题所在,这很愚蠢
0赞 chux - Reinstate Monica 6/5/2020
“如果 stdin 是 EOF,这将永远循环,等待一个永远不会到来的换行符。” --> 不同意这是肯定的。读取失败后,下一个读取的字符可能是“\n”。.然而,同意 c 应该是 int。
0赞 Thomas Jager 6/5/2020
@chux-ReinstateMonica 当我说那是 EOF 时,我不是说返回一次,我的意思是文件结束。stdingetcharEOFstdin