Why is "a" != "a" in C?

Solution 1:

What you are comparing are the two memory addresses for the different strings, which are stored in different locations. Doing so essentially looks like this:

if(0x00403064 == 0x002D316A) // Two memory locations
{
    printf("Yes, equal");
}

Use the following code to compare two string values:

#include <string.h>

...

if(strcmp("a", "a") == 0)
{
    // Equal
}

Additionally, "a" == "a" may indeed return true, depending on your compiler, which may combine equal strings at compile time into one to save space.

When you're comparing two character values (which are not pointers), it is a numeric comparison. For example:

'a' == 'a' // always true

Solution 2:

I'm a bit late to the party, but I'm going to answer anyway; technically the same bits, but from a bit different perspective (C parlance below):

In C, the expression "a" denotes a string literal, which is a static unnamed array of const char, with a length of two - the array consists of characters 'a' and '\0' - the terminating null character signals the end of the string.

However, in C, the same way you cannot pass arrays to functions by value - or assign values to them (after initialization) - there is no overloaded operator == for arrays, so it's not possible to compare them directly. Consider

int a1[] = {1, 2, 3};
int a2[] = {3, 4, 5};
a1 == a2 // is this meaningful? Yes and no; it *does* compare the arrays for
         // "identity", but not for their values. In this case the result
         // is always false, because the arrays (a1 and a2) are distinct objects

If the == is not comparing arrays, what does it actually do, then? In C, in almost all contexts - including this one - arrays decay into pointers (that point to the first element of the array) - and comparing pointers for equality does what you'd expect. So effectively, when doing this

"a" == "a"

you are actually comparing the addresses of first characters in two unnamed arrays. According to the C standard, the comparison may yield either true or false (i.e. 1 or 0) - "a"s may actually denote the same array or two completely unrelated arrays. In technical terms, the resulting value is unspecified, meaning that the comparison is allowed (i.e. it's not undefined behavior or a syntax error), but either value is valid and the implementation (your compiler) is not required to document what will actually happen.

As others have pointed out, to compare "c strings" (i.e. strings terminated with a null character) you use the convenience function strcmp found in standard header file string.h. The function has a return value of 0 for equal strings; it's considered good practice to explicitly compare the return value to 0 instead of using the operator `!´, i.e.

strcmp(str1, str2) == 0 // instead of !strcmp(str1, str2)