C: Behaviour of arrays when assigned to pointers

前端 未结 4 1488
名媛妹妹
名媛妹妹 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 20:56

    Say what?

    Your code allocates 6 bytes of memory and initializes it with the values 'h', 'e', 'l', 'l', 'o', and '\0'.

    It then allocates a pointer (number of bytes for the pointer depends on implementation) and sets the pointer's value to the start of the 5 bytes mentioned previously.

    You can modify the values of an array using syntax such as ptr[1] = 'a'.

    Syntactically, strings are a special case. Since C doesn't have a specific string type to speak of, it does offer some shortcuts to declaring them and such. But you can easily create the same type of structure as you did for a string using int, even if the syntax must be a bit different.

    0 讨论(0)
  • 2021-01-27 21:03

    "hello" is a string literal. It is a nameless non-modifiable object of type char [6]. It is an array, and it behaves the same way any other array does. The fact that it is nameless does not really change anything. You can use it with [] operator for example, as in "hello"[3] and so on. Just like any other array, it can and will decay to pointer in most contexts.

    You cannot modify the contents of a string literal because it is non-modifiable by definition. It can be physically stored in read-only memory. It can overlap other string literals, if they contain common sub-sequences of characters.

    Similar functionality exists for other array types through compound literal syntax

    int *p = (int []) { 1, 2, 3, 4, 5 };
    

    In this case the right-hand side is a nameless object of type int [5], which decays to int * pointer. Compound literals are modifiable though, meaning that you can do p[3] = 8 and thus replace 4 with 8.

    You can also use compound literal syntax with char arrays and do

    char *p = (char []) { "hello" };
    

    In this case the right-hand side is a modifiable nameless object of type char [6].

    0 讨论(0)
  • 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.)

    0 讨论(0)
  • 2021-01-27 21:17
    #include <stdio.h>
    
    main()
    {
       char * ptr;
    
       ptr = "hello"; 
    
      //instead of above tow lines you can write char *ptr = "hello" 
    
       printf("%p %s" ,"hello",ptr );
    
       getchar();
    
    }
    

    Here you have assigned string literal "hello" to ptr it means string literal is stored in read only memory so you can't modify it. If you declare char ptr[] = "hello";, then you can modify the array.

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