“a” == “b”。这是一个好的做法吗?

10

如果我用这种方式比较两个字符会发生什么:

if ('a' == 'b')
    doSomething();

我非常好奇当语言(和编译器)遇到这样的比较时会发生什么。当然,如果这是一种正确的做法,还是我必须使用类似于strcmp()的东西。

编辑 等等。
由于有人没有理解我的真正意思,我决定用另一种方式来解释。

char x, y;
cout << "Put a character: ";
cin >> x;
cout << "Put another character: ";
cin >> y;

if (x == y)
    doSomething();
当然,在if括号中,您可以将==替换为任何其他比较运算符。
我真正想知道的是:在C/C++中如何考虑字符?当编译器比较两个字符时,它如何知道'a'与'b'不同?它参考ASCII表吗?

9
优化编译器会意识到这是不可能的,并消除整个语句。 - Marc B
2
@MarcB 我怀疑这可能是一个抽象、简化的例子,使用了“魔法”字符代替变量。 - Andrew Marshall
1
我认为你实际上并不是在询问关于将'a'与'b'进行具体比较的问题,因为那显然总是会返回False,而是在询问如何比较单个字符。如果是这样,请编辑你的问题以明确表达。 - Lee-Man
1
@MarcB 我怀疑问题是在问抽象情况,而你的评论则针对他的具体示例。 - Lee-Man
4
也许原帖作者是一名戒掉 Java 的程序员,并期望类似 (new Char('a')).equals(new Char('b')) 这样的写法是正确的(或者更复杂一些,涉及到一个包装工厂)。 - Kerrek SB
'a' == 'b' 是在没有 false 的编程语言中表达 false 的好方法。 - fredoverflow
9个回答

20

你绝对可以通过比较运算符==安全地比较基本类型。


14
另外需要指出的是,'a'和'b'不是字符串,它们是字符(基本类型)。如果是 "a" == "b" 的话,情况就不同了。 - Eric Andres
1
关于基本类型,你的理解几乎是正确的,除了浮点数。我想你明白,在许多情况下 if ( doubleValue == 3.14 ) 是不正确的。 - borisbn
@borisbn,你的说法并不完全正确。如果floats/doubles的值在二进制上相等,它们就是相等的。在你的例子中,问题可能是由于舍入误差而不是==的错误导致的。请注意,即使在这种情况下,运算符==也会像它应该做的那样完成它的工作。 - triclosan
三氯生电脑总是按照你所写的方式行事,但有时候“你写了什么” != “你想要表达的意思”。)) - borisbn

13

在C和C++中,单个字符常量(以及char变量)是整数值(在数学意义上,不是int值的意义)。当您使用==进行比较时,编译器会将它们作为整数进行比较。您也可以使用其他整数比较运算符(如<<=等)。还可以进行加减运算。(例如,将数字字符转换为其数字值的一种常见习惯用法是c-'0'。)


5

对于单个字符,这种形式是正确的。如果编译时已知两个操作数(如您的示例中),则条件可以在编译时进行评估,并且不会导致任何代码。

请注意,char'a')与单个字符字符串("a")不同。 对于后者,比较具有不同的含义:它将比较指针而不是字符。


5

你的处理器将减去两个操作数,如果为零,则设置零条件位,那么你的值相同。

例如,在 ARM 机器上,你有 nzcv(负数、零、进位、溢出)位来告诉你发生了什么。


1
这可能与问题无关。实现一个没有这些属性的机器是可能的,因此,除非提问者明确说明所使用的平台,否则说这些是已经确定的事实是不准确的。(在x86和ARM的情况下,你是正确的,但我可以轻松地设计一组指令,使其不成立。) - greyfade
3
大多数情况下,您会有一个状态寄存器和一种数学运算。在我的示例中,这是减法,据我所知,大多数处理器都使用这种做法,可以将此高级代码转换为自己的汇编指令。我想说的是,在比较时,您会有两个带有值的寄存器,并通过一种数学运算进行比较。问题是“它如何知道'a'与'b'不同?”如果我理解错了,那就对不起。 - user1073834
问题是C ++如何处理'a' == 'b',而不是机器如何处理它。在这方面,机器的行为并不相关。 - greyfade

1

a 不等于 b,所以不会发生任何事情。

如果你的问题只是关于这是否正确的方式,那么答案是肯定的。


1
首先,'a'和'b'不是字符串,它们是字符。这种细微的差别因其涵义而重要。
你可以像比较整数和浮点数一样自如地比较字符与字符。通常不会这样做,因为结果总是相同的。也就是说,'a' == 'b'始终为false。
然而,如果你要比较字符串,你将需要使用类似于strcmp()的函数。

1
编译器只需插入一条比较两个字节是否相等的指令 - 这是非常高效的操作。当然,在您的情况下,'a'=='b' 等同于一个常量 false

0
编译器将比较数字ASCII代码。因此,'a'永远不等于'b'。但是,'a' < 'b'计算结果为true,因为在ASCII表中'a'出现在'b'之前。

假设正在使用ASCII编码。 - David Heffernan

0

当然,你想要使用变量,比如

char myChr = 'a' ;
if( myChr == 'b' ) puts( "It's b" ) ;

现在你可以开始思考"Yoda条件", 在那里你会这样做

if( 'b' == myChr )  puts( "It's a b" ) ;

这样,以防您在第二个示例中意外输入了一个等号:

if( 'b' = myChr ) puts( "It's a b" ) ;

这将会引发编译器错误。


这只会让代码变得更丑陋,任何好的编译器都会对 if (x=5) 给出警告。 - interjay
嗯,我想这有点虚伪,因为我自己不使用Yoda条件。但是,有些人喜欢它们。 - bobobobo

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