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

void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}

Why is the output No, not equal?

12333 次浏览

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

Because they are 2 separate const char*'s, pointers, no actual values. You are saying something like 0x019181217 == 0x0089178216 which of course returns NO

Use strcmp() instead of ==

According in C99(Section 6.4.5/6)

String Literals

It is unspecified whether these arrays are distinct provided their elements have the appropriate values.

So in this case it is unspecified whether both "a"s are distinct. An optimized compiler could keep a single "a" in the read-only location and both the references could refer to that.

Check out the output on gcc here

Pointers.

The first "a" is a pointer to a null-terminated ASCII string.

The second "a" is a pointer to another null-terminated ASCII string.

If you're using a 32-bit compiler, I'd expect "a"=="a"-4. I've just tried it with tcc/Win32 though, and I get "a"=="a"-2. Oh well...

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)

Some compilers have 'merge strings' option that you can use to force all constant strings to have the same address. If you would use that, "a" == "a" would be true.

Simply put, C has no built-in string comparison operator. It cannot compare strings this way.

Instead, strings are compared using standard library routines such as strcmp() or by writing code to loop through each character in the string.

In C, a string of text in double quotes returns a pointer to the string. Your example is comparing the pointers, and apparently your two versions of the string exist at different addresses.

But it is not comparing the strings themselves, as you seem to expect.

this question sets very good trail of explanation for all the beginers....
let me also contribute to it.....

as everybody above explained about , why you getting such output.

now if you want your prog. To print "yes equal" then

either use

if(strcmp("a", "a") == 0)
{


}

or
do not use "a" as strings, use them as characters....

if('a'=='a')
{
printf ("yes Equal");
}

in C characters are 1 byte short integer.......

You're comparing two memory address, so the result is not always going to be true. Did you try if('a' == 'a'){...}?

This guy does not use variables. Instead, he uses temporarily text arrays: a and a. The reason why

void main()
{
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}

does not work of course, is that you do not compare variables.
If you would create variables like:

char* text = "a";
char* text2 = "a";

then you could compare text with text2, and it should be true

Maybe you shouldn't forget to use { and } =)

void main() {
if("a" == "a")
{
printf("Yes, equal");
}
else
{
printf("No, not equal");
}
}

if comparision between character is always in single quote, e.g.

if('a' == 'a')

and C can't support string comparision like "abc" == "abc"

It's done with strcmp("abc","abc")