Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compare two equal array in c but output shows unequal

After a long break,I am back to C but getting confused even on some simple issues. So one is here.

Here is the simple code :

 #include<stdio.h>

 int main() {

    char str1[]="hello";
    char str2[]="hello";

    if(str1==str2)
            printf("equal");  
    else
            printf("unequal");
} 

Output: unequal

but when I tried this one ,it worked

  char *str1="hello";
  char *str2="hello";

Output equal

Please if anyone can provide a detailed explanation for it. Can someone tell me what exactly does C99 standard say about the situation ???

like image 645
Udit Gupta Avatar asked Dec 10 '22 03:12

Udit Gupta


2 Answers

When you do == with pointers (which is what str1 and str2 are in both cases1) all you are doing is comparing the two addresses to see if they are the same. When you do

char str1[]="hello";
char str2[]="hello";

You are creating two arrays on the stack that hold "hello". They are certainly at different memory locations, so str1 == str2 is false. This is like

char str1[6];
str1[0] = 'h';
str1[1] = 'e';
str1[2] = 'l';
str1[3] = 'l';
str1[4] = 'o';
str1[5] = '\0'; 

// and the same thing for str2

When you do

char *str1="hello";
char *str2="hello";

You are creating two pointers to the global data "hello". The compiler, seeing that these string literals are the same and cannot be modified, will make the pointers point to the same address in memory, and str1 == str2 is true.

To compare the content of two char*s, use strcmp:

// strcmp returns 0 if the two strings are equal
if (strcmp(str1, str2) == 0)
    printf("Equal");
else
    printf("Not equal");

This is roughly the equivalent of

char *a, *b;

// go through both strings, stopping when we reach a NULL in either string or
// if the corresponding characters in the strings don't match up
for (a = str1, b = str2; *a != '\0' && *b != '\0'; ++a, ++b)
    if (*a != *b)
        break;

// print Equal if both *a and *b are the NULL terminator in
// both strings (i.e. we advanced a and b to the end of both
// strings with the loop)
if (*a == '\0' && *b == '\0')
     printf("Equal");
else
     printf("Not equal");


1 In the char* version, this is true. In the char[] version, str1 and str2 are really arrays, not pointers, however when used in str1 == str2, they decay to pointers to the first elements of the arrays, so they are the equivalent of pointers in that scenario.
like image 154
Seth Carnegie Avatar answered Dec 11 '22 15:12

Seth Carnegie


You're comparing the pointers to the strings and not the strings themselves, but since they are two different strings, they are not "==" equal.

If you're comparing strings in C, you'll need to use strcmp(str1, str2) a'la

if(strcmp(str1, str2) == 0) {

A word of caution; if you had declared the strings as char* instead of char[], some compilers would actually show your comparison as equal, as the compiler realizes the two strings are equal and collapse them into one. That means, they'd both point to the same string, and the pointer comparison would be true.

Been bitten by that once, never again, darn VAX compiler... :)

like image 38
Joachim Isaksson Avatar answered Dec 11 '22 15:12

Joachim Isaksson