Can Someone explain to me why?

Pages: 12
Why does a and b not equal each other?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

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

        if  (a == b)
        {
            cout << a << " and " << b << " are equal.\n" << endl;
        }
        else
        {
            cout << a << " and " << b << " are not equal.\n" << endl;
        }
    return 0;
}

Jim and Jim are not equal.

Process returned 0 <0x0>   execution time : 0.060 s
Press any key to continue.
Last edited on
You can't compare C-style strings like that.

You'd need to make use of strcmp.
http://www.cplusplus.com/reference/cstring/strcmp/
you cannot compare c-like strings like that. Either use std::string class to store your string and compare them with == or use strcmp() function to compare your strings
Okay, you are telling me I can't compare strings like that, well, that I already know (it won't work), but you are not telling me why it won't work. What's going on inside of the brain of c++ that rejects this way of doing it?
Last edited on
Let consider statements

1
2
char a [] = "Jim";
char b [] = "Jim";


What do they mean?

The compiler allocated some memory region to contain elements of array a and another memory region to contain elements of array b. And the compiler initialized these regions with characters of string literals "Jim".

Now consider expression

a == b

In expressions names of arrays are implicitly converted to addresses of their first elements. As I noted above a and b occupy different regions of memory so their addresses are also different. In this expression you are comparing initial addresses of these memory regions. Of course they are different. So the value of the expression is equal to false.

Last edited on
What you essentially have is a null-terminated array of characters.

Like any other array in C/C++, you can't compare them like that.
One more interesting example. Expression

"Jim" == "Jim"

can be either equal to true or to false. Why? Because the C++ standard says that any compiler can place two string literals with the same content either in the same memory region or in two separate different regions. It usually depends on a compiler option.

Again in this expression it is addresses of the memory regions that are compared.:)
Last edited on
That it will be more clear for you then your program can be rewritten as


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

using namespace std;

int main()
{
        char a [] = "Jim";
        char b [] = "Jim";
        char *p = a;
        char *q = b;

        if  (p == q)
        {
            cout << ( void * )p << " and " << ( void * )q << " are equal.\n" << endl;
        }
        else
        {
            cout << ( void * )p << " and " << ( void * )q << " are not equal.\n" << endl;
        }
    return 0;
}


In fact it is what your program is trying to do.
Be careful - those should be const characters, as you cannot change them.
L B (3182)
Be careful - those should be const characters, as you cannot change them.


What should be const characters?!!!


a and b are arrays so he can change them.
Ah, so creating weak arrays of characters from string literals allows the characters to be modified at runtime? I didn't know this - yet another quirk of C++ with arrays and string literals.
Well, it's an array, and the elements are not constant. Arrays are ALWAYS allocated on the stack, so of course he can modify it during runtime. A string literal is usually only in the ROM of the program, not on the stack.
Hey Vlad, say, this "(void*)p", is this a way to dereference the *p?

I'm new, so... just never seen it before.

Thanks
No, it is not a dereferencing. It is a casting of char * to void * that to output the address of a character array instead of its elements.
Last edited on
Nexius wrote:
Well, it's an array, and the elements are not constant. Arrays are ALWAYS allocated on the stack, so of course he can modify it during runtime. A string literal is usually only in the ROM of the program, not on the stack.
I know, the part I didn't know was that the string literal was actually copied into the array on the stack. I thought the [] just degraded into a pointer in that case, but apparently it still acts as an array.
what is *p?

I looked for a reference but couldn't find one.

jim
int *p; is a declaration of a pointer to int.
Last edited on
No, it is not a dereferencing. It is a casting of char * to void * that to output the address of a character array instead of its elements.

Thanks!
vlad from moscow's code and results:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

using namespace std;

int main()
{
        char a [] = "Jim";
        char b [] = "Jim";
        char *p = a;
        char *q = b;

        if  (p == q)
        {
            cout << ( void * )p << " and " << ( void * )q << " are equal.\n" << endl;
        }
        else
        {
            cout << ( void * )p << " and " << ( void * )q << " are not equal.\n" << endl;
        }
    return 0;
}


0x22ff44 and 0x22ff40 are not equal.

Process returned 0 <0x0>   execution time : 0.060 s
Press any key to continue.


So, am I correct when I say C++ is comparing the addresses and not the contents of the array? Or is it a little more complicated than that?
Pages: 12