C: Behaviour of arrays when assigned to pointers

前端 未结 4 1489
名媛妹妹
名媛妹妹 2021-01-27 20:17
#include 

main()
{
  char * ptr;

  ptr = \"hello\";


  printf(\"%p %s\" ,\"hello\",ptr );

  getchar();

}

Hi, I am trying to underst

4条回答
  •  [愿得一人]
    2021-01-27 21:11

    The first thing you should do is read section 6 of the comp.lang.c FAQ.

    The string literal "hello" is an expression of type char[6] (5 characters for "hello" plus one for the terminating '\0'). It refers to an anonymous array object with static storage duration, initialized at program startup to contain those 6 character values.

    In most contexts, an expression of array type is implicitly converted a pointer to the first element of the array; the exceptions are:

    • When it's the argument of sizeof (sizeof "hello" yields 6, not the size of a pointer);
    • When it's the argument of _Alignof (a new feature in C11);
    • When it's the argument of unary & (&arr yields the address of the entire array, not of its first element; same memory location, different type); and
    • When it's a string literal in an initializer used to initialize an array object (char s[6] = "hello"; copies the whole array, not just a pointer).

    None of these exceptions apply to your code:

    char *ptr;
    ptr = "hello";
    

    So the expression "hello" is converted to ("decays" to) a pointer to the first element ('h') of that anonymous array object I mentioned above.

    So *ptr == 'h', and you can advance ptr through memory to access the other characters: 'e', 'l', 'l', 'o', and '\0'. This is what printf() does when you give it a "%s" format.

    That anonymous array object, associated with the string literal, is read-only, but not const. What that means is that any attempt to modify that array, or any of its elements, has undefined behavior (because the standard explicitly says so) -- but the compiler won't necessarily warn you about it. (C++ makes string literals const; doing the same thing in C would have broken existing code that was written before const was added to the language.) So no, you can't modify the elements of "hello" -- or at least you shouldn't try. And to make the compiler warn you if you try, you should declare the pointer as const:

    const char *ptr; /* pointer to const char, not const pointer to char */
    ptr = "hello";
    

    (gcc has an option, -Wwrite-strings, that causes it to treat string literals as const. This will cause it to warn about some C code that's legal as far as the standard is concerned, but such code should probably be modified to use const.)

提交回复
热议问题