Comparing two char* and two char[ ] strings in C

Viewed 1054
#include <stdio.h>

int main(){
    char a[] = "bar";
    char b[] = "bar";
    printf("%d\n", (a==b));

    char* x = "bar";
    char* y = "bar";
    printf("%d\n", (x==y));
 }  

Output :

0 
1

I know we can't compare C char arrays using the == operator as it compares memory locations, but why does it work in the second case ?

3 Answers

In the first case, as you defined two arrays, the compiler allocated two separate storage for them, so a and b are not equal.

But, for the second case, as you initialized two pointers with the same string literal, the compiler found them the same string, and point the two pointers into the same address which is the start address of that string literal ("bar"). However, as @David said, this is not happened necessarily, and in some situation, removing some optimization, or based on some compiler, x and y might not be the same.

The output makes sense because the memory storage for the arrays are not equal. For the char's, their literal characters are compared. Try running this example.

int main(void) {
    char a[] = "bar";
    char b[] = "bar";

    printf("Arrays Test: %x == %x ? %d\n",&a,&b,(a==b));


    char* x = "bar";
    char* y = "bar";

    printf("Literals Test: %x == %x ? %d, however x == y ? %d\n",&x,&y, (&x==&y),(x==y));

    return 0;
}

This online runnable example shows that the char's memory references are not the same.

If you wanted to see if the array's content is equal, you would need to call every char in the array and compare it to the secondary array manually. You could potentially end execution faster by checking the sizes of the array against each other.

An additional point is that "pointerizing" the chars or arrays makes no difference in this scope of comparison.

This is implementation-dependent

In the 1st case, a and b have separate storage space, so their address won't be equal.

However, the compiler may identify that the strings x and y are pointing to is identical, so it may optimize by making them point to the same location, since you can't modify it. However, as the standard does not require to do so, you can't rely on the result. It's an optional optimization. The compiler can still generate two identical strings and make x and y point to them separately.

Related