Pointers and assignment, how does it work with different types?

前端 未结 3 1600
后悔当初
后悔当初 2021-01-17 02:09

I\'m doing \"Learn C the hard way\" for self-study coming from knowing a bit of Python. I have read several tutorials, but I can\'t get my head around how pointers and assig

相关标签:
3条回答
  • 2021-01-17 02:50
    int *anint = 42;
    

    42 is an integer literal and anint is supposed to hold the address pointing to an integer and not by integer itself.

    char *pointer_to_strlit;
    char *strlit = "some stuff";    // Should be const char *strlit = "some stuff";
    pointer_to_strlit = &strlit;    // Wrong
    

    &strlit gives address of pointer ( i.e., char ** ) while pointer_to_strlit is of type char*. So, it should be

    pointer_to_strlit = strlit;
    

    String literals reside in read only location. Turn on the warnings and compiler should give you some decent messages.

    0 讨论(0)
  • 2021-01-17 02:56

    Hang in there! Pointers will make sense after more practice. But when in doubt, try to reason about what each value means. Using pen and paper to try to draw each byte in memory really helps.

    char *pointer_to_strlit; - here you declare a pointer to a character. As you probably already know, a string in C is represented by a pointer to the first character of that string. The string is expected to be null-terminated. This means that eventually there should be an ASCII 0 character indicating that the string has ended.

    char *strlit = "some stuff"; - your program's memory will contain characters for this string (11 characters to be exact -- 10 for the text you see, and 1 for the null terminator). Here you declare another pointer, this time pointing to first character "s" from that string.

    pointer_to_strlit = &strlit; - this sets the value of pointer_to_strlit to the address of the pointer strlit. This is probably not what you want here.

    If things get confusing, try to think of each pointer as a plain old number -- that's essentially what a pointer is, a huge number representing an address in memory. Let's look at the above again:

    char *pointer_to_strlit; - Here the value of pointer_to_strlit is undefined since you didn't set it yet.

    char *strlit = "some stuff"; - Let's say the address of the first "s" is 1234500. The value of strlit will be that number, 1234500.

    pointer_to_strlit = &strlit; - But what is the address of strlit itself? It's some other value, let's say 1234600. The value of pointer_to_strlit will now be 1234600.

    Try to print pointer_to_strlit as a %s now, and your program will crash -- at the address 1234600 is not the first character of a string, but another number -- one of the bytes of the huge number, the pointer. The code will try to traverse what it thinks is a string to look for the null-terminator, eventually crashing when it reaches inaccessible memory.

    0 讨论(0)
  • 2021-01-17 03:07
    int *anint = 42;
    

    This declaration is incorrect. anint is a pointer to an int, but you've initialized it as an int.

    char *pointer_to_strlit;
    char *strlit = "some stuff";
    

    These declarations are fine. "some stuff" is a string literal, which in C is a char *, so it's fine to initialize strlit with it.

    pointer_to_strlit = &strlit;
    

    This is incorrect. &strlit is a char**, since it's the address of a char*.

    printf(
        "I print strlit: %s\n"
        "I print it again by pointing to it: %s\n"
        "I print where the pointer is pointing: %p\n", 
        strlit, *pointer_to_strlit, pointer_to_strlit
    );
    

    Here you use strlit as %s, which is fine. Then you use *pointer_to_strlit as %s, which is bad: %s expects a pointer to a null-terminated string, you gave it a char, so it segfaults.

    0 讨论(0)
提交回复
热议问题