Why isn't (“Maya” == “Maya”) true in C++?

前端 未结 8 1298
野趣味
野趣味 2020-12-29 05:21

Any idea why I get \"Maya is not Maya\" as a result of this code?

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


        
相关标签:
8条回答
  • 2020-12-29 05:24

    You are not comparing strings, you are comparing pointer address equality.

    To be more explicit -

    "foo baz bar" implicitly defines an anonymous const char[m]. It is implementation-defined as to whether identical anonymous const char[m] will point to the same location in memory(a concept referred to as interning).

    The function you want - in C - is strmp(char*, char*), which returns 0 on equality.

    Or, in C++, what you might do is

    #include <string>

    std::string s1 = "foo"

    std::string s2 = "bar"

    and then compare s1 vs. s2 with the == operator, which is defined in an intuitive fashion for strings.

    0 讨论(0)
  • 2020-12-29 05:24

    My compiler says they are the same ;-)

    even worse, my compiler is certainly broken. This very basic equation:

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

    produces:

    23 - 523 = 1
    
    0 讨论(0)
  • 2020-12-29 05:33

    The output of your program is implementation-defined.

    A string literal has the type const char[N] (that is, it's an array). Whether or not each string literal in your program is represented by a unique array is implementation-defined. (§2.13.4/2)

    When you do the comparison, the arrays decay into pointers (to the first element), and you do a pointer comparison. If the compiler decides to store both string literals as the same array, the pointers compare true; if they each have their own storage, they compare false.

    To compare string's, use std::strcmp(), like this:

    if (std::strcmp("Maya", "Maya") == 0) // same
    

    Typically you'd use the standard string class, std::string. It defines operator==. You'd need to make one of your literals a std::string to use that operator:

    if (std::string("Maya") == "Maya") // same
    
    0 讨论(0)
  • 2020-12-29 05:35

    Because you are actually comparing two pointers - use e.g. one of the following instead:

    if (std::string("Maya") == "Maya") { /* ... */ } 
    if (std::strcmp("Maya", "Maya") == 0) { /* ... */ }
    

    This is because C++03, §2.13.4 says:

    An ordinary string literal has type “array of n const char

    ... and in your case a conversion to pointer applies.

    See also this question on why you can't provide an overload for == for this case.

    0 讨论(0)
  • 2020-12-29 05:36

    C and C++ do this comparison via pointer comparison; looks like your compiler is creating separate resource instances for the strings "Maya" and "Maya" (probably due to having an optimization turned off).

    0 讨论(0)
  • 2020-12-29 05:38

    Any idea why i get "Maya is not Maya" as a result

    Because in C, and thus in C++, string literals are of type const char[], which is implicitly converted to const char*, a pointer to the first character, when you try to compare them. And pointer comparison is address comparison.
    Whether the two string literals compare equal or not depends whether your compiler (using your current settings) pools string literals. It is allowed to do that, but it doesn't need to. .

    To compare the strings in C, use strcmp() from the <string.h> header. (It's std::strcmp() from <cstring>in C++.)

    To do so in C++, the easiest is to turn one of them into a std::string (from the <string> header), which comes with all comparison operators, including ==:

    #include <string>
    
    // ...
    
    if (std::string("Maya") == "Maya") 
       std::cout << "Maya is Maya\n";
    else
       std::cout << "Maya is not Maya\n";
    
    0 讨论(0)
提交回复
热议问题