对于体验程序员来说,这可能是一个愚蠢的问题......但无论如何,我只想弄明白。 if(“Hello”== $ helloString)和 if(helloString ==“Hello”)之间有什么区别?我认为if语句中的顺序并不重要,但我想我的想法一定有问题。有人可以向我赎罪吗?就像在什么样的情况下,人们会使用第一个/第二个if语句来进行平等测试?谢谢!!
答案 0 :(得分:7)
这是一项“安全”措施。如果您有拼写错误,并且遗漏了其中一个'='字符,那么您正在进行分配而不是比较。
if (some_string = "Hello")
覆盖字符串,if
被认为是真的(假设使用std::string
)。另一方面:
if ("Hello" = somestring)
是编译错误。
看起来有点奇怪,但它在某些圈子里被认为是一种好的,预防性的编码措施。
答案 1 :(得分:2)
你的想法有什么问题?我假设随机$
符号是拼写错误。两行都检查对象helloString
是否实际上等于文字字符串"Hello"
。排序是样式首选项 - 历史上常量放在==
的左侧以防止意外分配(通过=
),尽管编译器现在应该警告这种行为。
请注意,这仅适用于std::string
类型的对象,这些对象会重载==
个运算符,并允许进行比较。如果您使用char *
的C风格字符串,则无效。
#include <string>
#include <iostream>
int main()
{
std::string helloString = "Hello";
char *helloPtr = "Hello";
if (helloString == "Hello") { std::cout << "Equal 1\n"; }
if ("Hello" == helloString) { std::cout << "Equal 2\n"; }
if (helloPtr == "Hello") // not a *wise* comparison because you are comparing pointers
{
}
}
答案 2 :(得分:1)
作为Tom mention s,您应该使用strcmp
或strncmp
字符串。在其他情况下,一些编码样式建议将文字放在变量之前,以避免常见但有时很难的错误:
if (foo = 5)
{
...
}
编码器可能意味着foo == 5
,只有当foo等于5时才是真的,而是指示编译器将foo分配给5并且每次都执行if主体。通过遵循 literals first 规则,编码器会写:
if (5 = foo)
{
...
}
这是无效的,不会编译,因为5不是l值。编码员会马上发现他的错误。
另一方面,if或while条件中的赋值实际上是一种常见的习惯用法,并且许多C编码器反对 literals first 样式,因为它有点难以阅读,出于同样的原因“如果安格斯是一个苏格兰人”比“如果一个苏格兰人是安格斯”的扫描更好,即使两者在技术上是等价的。
答案 3 :(得分:1)
有些编译器允许带有$符号的标识符作为非标准扩展名......没什么大不了的。
这个问题有两个方面 - 你感兴趣的问题并不清楚:
if("Hello" == helloString)
,因为如果=
是==
,它会产生编译器错误意外输入而不是struct X
{
// as a member function
bool operator==(const char* rhs) const { return <some expression>; }
};
// as a non-member function (use this OR the member function)
bool operator==(const X& lhs, const char* rhs) { return <some expression>; }
// only possible as a non-member function, as X doesn't appear on the left of ==
bool operator==(const char* lhs, const X& rhs) { return <some expression>; }
对于operator ==,用户可以为他们定义的类/结构提供自己的比较运算符:
struct X
{
bool operator(const X& rhs) const { return <some expression>; }
};
OR
bool operator==(const X& lhs, const X& rhs) { return <some expression>; }
您还可以将两个X之间的相等定义为非成员函数的成员...
struct X
{
X(const char* p) /* initialiser list eg. */ : p_(p) { <option code> }
};
但是,这些函数只允许对字符串文字进行比较(你的“Hello”是一个字符串文字),如果你告诉编译器允许它通过一个合适的构造函数隐式地从字符串文字创建一个X:
("Hello"==helloString)
如果helloString是我们的X类型,这将允许(X("Hello") == helloString)
解析为:
X::operator==(const X&)
其中 - 如上所述 - 您提供的是会员operator==(const X&, const X&)
或非会员explicit
。
将构造函数更改为struct X
{
explicit X(const char* p) /* initialiser list eg. */ : p_(p) { <option code> }
};
可防止编译器隐式执行X的动态构造,这通常是最好的,因为隐式转换可能在不打算时发生,并且使得预期的解决方案不明确或提供不需要的结果
struct X
{
operator const char*() const { return <some expression>; }
};
可以为用户定义的类型(类/结构)计算此表达式的另一种方法是允许编译器创建一个已知道如何与用户定义类型的字符串文字进行比较的类型。编译器知道如何比较两个字符串文字,但它不像初学者期望的那样做 - 而是比较存储文本的内存地址而不是存储在那些地址的文本内容。 。这通常对初学者没用。对于记录,转换运算符如下所示:
if (strcmp("Hello", someString)) // compare textual content
...
这比非显式构造函数更不可取 - 它们具有相同的问题,使某些预期的匹配变得模糊,但也可以提供不太有用的字符串地址比较而不是字符串内容比较。请注意,C ++标准的std :: string提供了一个c_str()函数,当您需要字符串内容的地址时,必须显式调用该函数,并且在对字符串进行任何修改后此类地址可能会变为无效(例如,附加更多文本)
最后,如果someString不是一个类/结构,但是是另一个字符串文字,那么 - 如上所述 - 编译器将比较地址而不是字符串内容。您可以使用strcmp()函数来比较文本内容:
if (X("Goodbye\000Cruel\000World", 19) == someString))
...
如果字符串内容未嵌入任何NUL(0)字符,则此方法有效。否则,字符串类可以提供指针和数据长度的构造函数(如std :: string那样),允许:
{{1}}
答案 4 :(得分:0)
C ++中没有 $ 运算符,因此该语句无效:
if("Hello"==$helloString)
答案 5 :(得分:0)
订单无关紧要。但是,如果helloString是std :: string而不是C字符串,则只应使用==运算符。另外,C ++中没有$运算符,所以你应该省略它。
例如,如果helloString是C字符串(例如char *),请使用strcmp函数:
if(strcmp("Hello", other_str) == 0) {
// they are equal
} else {
// they are not equal
}
或者如果helloString是std :: string,则可以使用==运算符:
if("Hello" == helloString) {
// they are equal
} else {
// they are not equal
}
编辑:由于评论,我做了大量修改。谢谢你们。
答案 6 :(得分:0)
如果未定义其中一个或另一个。在std :: string的情况下,情况并非如此。但是可以定义这样的函数:
bool operator==(X lhs, Y rhs);
然后你可以像这样调用这个函数:
X x;
Y y;
if(x == y) {...}
但你不能这样做:
if(y == x) {...}
除非你定义另一个这样的函数:
bool operator==(Y lhs, X rhs);