简体   繁体   中英

C language. Is this pointers comparison or something else?

I've been learning Python for a while and now I found myself exploring some C basics. After been reading about pointers I played a bit with some of the related syntax and I wrote a very simple script:

#include <stdio.h>

int main(void)
{
    char *k_ptr = "home";
    char *j_ptr = "pen";

    printf("string: %s, address: %p\n", k_ptr, &k_ptr);
    printf("string: %s, address: %p\n", j_ptr, &j_ptr);

    if (k_ptr == j_ptr)
    {
        printf("It's equal.\n");
    }
    else
    {
        printf("It's not equal\n.");
    }
}

I learned that in C, string comparison can be done with strcmp() and array comparison is always false. But then:

-when I compare k_ptr == j_ptr what am I actually comparing?

-why the program returns correctly if the two string are equal or not if this is not a string comparison?

-why this syntax seems to work only if I use strings?

You declared two pointers

char *k_ptr = "home";
char *j_ptr = "pen";

that point to first characters of the corresponding string literals used as initializers.

That is the pointer k_ptr contains the address of the letter 'h' of the first string literal and the pointer j_ptr contains the address of the letter 'p' of the second string literal.

The string literals occupy different extents of memory. So this comparison

if (k_ptr == j_ptr)

always will yield false. That is the addresses of the string literals (their first characters) are different.

Take into account that even you will write for example

char *k_ptr = "Hello";
char *j_ptr = "Hello";

then it is not necessary that the result of the comparison

if (k_ptr == j_ptr)

will yield true. The result depends on compiler options. The compiler can either store identical string literals as one string literal or as two different string literals.

From the C Standard (6.4.5 String literals)

7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

If you want to compare the string literals themselves instead of their addresses then you need to use the standard C string function strcmp declared in the header <string.h>

For example

if ( strcmp( k_ptr, j_ptr ) == 0 )
{
    // string literals are equal
}

As for your question

-why this syntax seems to work only if I use strings?

then string literals are unnamed character arrays. Used in expressions they implicitly converted (with rare exceptions) to pointers to their first elements.

In fact you can use the same syntax with for example integer arrays like

int a[] = { 1, 2, 3 };
int *p = a;

Now the pointer p points to the first element of the array a .

when I compare k_ptr == j_ptr what am I actually comparing?

You are comparing an integer-type value representing the address of the data in memory. The addresses you display in your printf statements are the addresses of the pointers themselves, while here you are comparing the addresses the pointers point to.

why the program returns correctly if the two string are equal or not if this is not a string comparison?

It's constant-value optimization. If the compiler sees the same string constant happen in the code the second time, it refers it to the same memory. It's no reliable though, so you should not rely on this behavior at all. BTW, the same happens in Python when you compare strings with the is operator. Two different string objects are not the same object, so the operator should return False , but it returns True if you try it in a simple program like this. That's the same optimization implemented in two different programs (GCC and CPython).

why this syntax seems to work only if I use strings?

Because they are pointers to a constant value, which allows such optimization to happen.

when I compare k_ptr == j_ptr what am I actually comparing?

k_ptr is a pointer. j_ptr is a pointer. k_ptr == j_ptr tests whether they point to the same place.

-why the program returns correctly if the two string are equal or not if this is not a string comparison?

If two pointers point to the same place, then of course the thing they point to is equal to itself. If they point to different places, the things they point to may or may not be equal, and so comparing the pointers is not the same as comparing the things they point to.

-why this syntax seems to work only if I use strings?

It does not work.

-when I compare k_ptr == j_ptr what am I actually comparing?

You are comparing the pointer values themselves, as opposed to the data to which they point. Valid pointer values are addresses of objects. Two valid pointer values of the same type are equal if and only if they point to the same object.

-why the program returns correctly if the two string are equal or not if this is not a string comparison?

Because different strings necessarily have different addresses. The pointer comparison determines whether the two pointers point to the same object, without regard to the values of the pointed-to objects.

Note that it is possible to have different strings in this sense that compare equal via strcmp() . The one kind of comparison has nothing to do with the other.

-why this syntax seems to work only if I use strings?

It's unclear what syntax you mean. There is very little in your program that is specific to strings, but of course you cannot write random gibberish and expect a C compiler to accept it.

Certainly you can perform == comparisons on pointers of other types, and it has the same significance I've already described.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM