Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么不是';t(“Maya”在C+中为真+;?_C++_String_Equality - Fatal编程技术网

C++ 为什么不是';t(“Maya”在C+中为真+;?

C++ 为什么不是';t(“Maya”在C+中为真+;?,c++,string,equality,C++,String,Equality,知道为什么我会因为这段代码而得到“Maya不是Maya”吗 if ("Maya" == "Maya") printf("Maya is Maya \n"); else printf("Maya is not Maya \n"); 您不是在比较字符串,而是在比较指针地址相等性 更明确地说: “foo baz bar”隐式定义了一个匿名const char[m]。实现定义为相同的匿名const char[m]是否指向内存中的相同位置(这一概念称为interning) 在C语言中,您需

知道为什么我会因为这段代码而得到“Maya不是Maya”吗

if ("Maya" == "Maya") 
   printf("Maya is Maya \n");
else
   printf("Maya is not Maya \n");

您不是在比较字符串,而是在比较指针地址相等性

更明确地说:

“foo baz bar”隐式定义了一个匿名
const char[m]
。实现定义为相同的匿名const char[m]是否指向内存中的相同位置(这一概念称为interning)

在C语言中,您需要的函数是strmp(char*,char*),它在相等时返回0

或者,在C++中,你可以做的是

#包括

std::string s1=“foo”

std::string s2=“bar”


然后将s1与s2与
==
运算符进行比较,该运算符是以直观的方式为字符串定义的。

因为您实际上是在比较两个指针-例如,使用以下其中一个:

if (std::string("Maya") == "Maya") { /* ... */ } 
if (std::strcmp("Maya", "Maya") == 0) { /* ... */ }
这是因为C++03,§2.13.4规定:

普通字符串文字的类型为“数组的n
const char

。。。在您的情况下,将应用指针转换


另请参见本例中为什么不能为
==
提供重载。

您所做的是将一个字符串的地址与另一个字符串的地址进行比较。根据编译器及其设置,有时相同的文本字符串将具有相同的地址,有时则不具有相同的地址(很明显,您会发现)。

我的编译器说它们是相同的;-)

更糟糕的是,我的编译器肯定坏了。这是一个非常基本的方程式:

printf("23 - 523 = %d\n","23"-"523");
产生:

23 - 523 = 1
你知道为什么我会得到“玛雅不是玛雅”吗

因为在C中,因此在C++中,字符串文字是类型<代码> const char []/COD>,当您尝试比较它们时,它隐式地转换为<代码> const char */COD>,指向第一个字符的指针。strong>和指针比较是地址比较。
两个字符串文本的比较是否相等取决于编译器(使用当前设置)是否池字符串文本。允许这样做,但不需要

要比较C中的字符串,请使用
标题中的
strcmp()
。(<代码> STD::StrucMP[])/<代码>从代码> <代码> C++ > < /P>

在C++中这样做,最简单的是将其中一个转换成<代码> STD::String (从<代码> <代码>标题),它包含所有比较运算符,包括<代码>=< /COD>:

#include <string>

// ...

if (std::string("Maya") == "Maya") 
   std::cout << "Maya is Maya\n";
else
   std::cout << "Maya is not Maya\n";
#包括
// ...
如果(std::string(“Maya”)==“Maya”)

STD:CUT< P> C和C++通过指针比较进行比较;看起来编译器正在为字符串“Maya”和“Maya”创建单独的资源实例(可能是由于禁用了优化)。

程序的输出由实现定义

字符串文字的类型为
constchar[N]
(即,它是一个数组)。程序中的每个字符串文字是否由唯一数组表示是由实现定义的。(§2.13.4/2)

进行比较时,数组会衰减为指针(指向第一个元素),然后进行指针比较。如果编译器决定将两个字符串文本存储为同一数组,指针将比较true;如果它们各自有自己的存储空间,则比较为false

要比较字符串,请使用std::strcmp()
,如下所示:

if (std::strcmp("Maya", "Maya") == 0) // same
通常,您会使用标准字符串类,
std::string
。它定义
运算符==
。要使用该运算符,您需要将其中一个文本设置为
std::string

if (std::string("Maya") == "Maya") // same
事实上,“因为您的编译器在本例中没有使用字符串池”,这是技术上正确的,但不是特别有用的答案:)

<>这是很多原因之一,在标准模板库中,当你想用C++中的字符串做任何有用的事情时,标准强的模板中的类现在已经存在,这是一个问题,几乎所有的人都在学习中很早就学会了C或C++。 让我解释一下

基本上,在C语言时代,所有字符串都是这样工作的。字符串只是内存中的一组字符。当程序执行时,嵌入到C源代码中的字符串将被转换为一组字节,这些字节表示正在运行的机器代码中的字符串

这里的关键部分是一个好的老式C风格的“字符串”是内存中的字符数组。该内存块通常通过指针来引用,指针是内存块开始的地址。通常,当您在C中引用“字符串”时,您指的是该内存块或指向它的指针。C本身没有字符串类型;字符串只是一行中的一堆字符

在代码中编写此代码时:

"wibble"
然后,编译器提供一个内存块,其中包含按该顺序表示字符“w”、“i”、“b”、“b”、“l”、“e”和“\0”的字节(编译器在末尾添加一个零字节,即“空终止符”).在C语言中,标准字符串是以null结尾的字符串:从给定内存地址开始,一直持续到下一个零字节的字符块。)

当你开始比较这样的表达式时,会发生这样的情况:

if ("Maya" == "Maya")
在这个比较点上,编译器——特别是在您的例子中;请参阅我最后对字符串池的解释--创建了两个独立的内存块,以容纳两组不同的字符,它们都设置为“M”、“a”、“y”、“a”、“0”

当编译器在这样的引号中看到字符串时,“在引擎盖下”将构建一个字符数组,而字符串本身“Maya”将充当字符数组的名称。因为数组的名称实际上是指针,指向数组的第一个字符,所以表达式“Maya”的类型是指向字符的指针

当你来的时候