C pointer : array variable

后端 未结 7 498
盖世英雄少女心
盖世英雄少女心 2021-01-20 18:09

I read this in my book (and many sources on the internet):

The array variable points to the first element in the array.

相关标签:
7条回答
  • 2021-01-20 18:42

    The array variable is the whole array. It decays into a pointer to the first element of the array.

    If you look at the types:

    • msg is of type char [16]
    • &msg is of type char (*)[16]
    • &msg[0] is of type char *

    So in a context where msg can decay into an array, for example when passed as an argument, its value would be equal to &msg[0].

    Let me draw this:

    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
    |s|t|a|c|k| |o|v|e|r| |f|l|o|w|\0|
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
    

    Imagine the starting point of this array, where 's' is located is address 0x12345678.

    • msg itself, refers to the whole 16 bytes of memory. Like when you say int a;, a refers to 4 bytes of memory.
    • msg[0] is the first byte of that 16 bytes.
    • &msg is the address where array begins: 0x12345678
    • &msg[0] is the address of first element of array: 0x12345678

    This is why the values of &msg and &msg[0] are the same, but their types are different.

    Now the thing is, msg by itself is not a first class citizen. You cannot for example assign arrays. That is why, in most of the cases, the array will decay into its pointer.

    If you know function pointers, this is very similar:

    int array[10];
    int function(int);
    
    • In int *var = array, array decays to a pointer (&array)
    • In void *var = function, function decays to a pointer (&function)

    Note that, in case of function pointers, we like to keep the type, so we write:

    int (*var)(int) = function;
    

    Similarly, you can do with arrays:

    int (*var)[10] = array;
    
    0 讨论(0)
  • 2021-01-20 18:45

    When you use an array expression, the compiler converts it to a pointer to the first element. This is an explicit conversion specified by the 1999 C standard, in 6.3.2.1 3. It is a convenience for you, so that you do not have to write &array[0] to get a pointer to the first element.

    The conversion happens in all expressions except when an array expression is the operand of sizeof or the unary & or is a string literal used to initialize an array.

    You can see that an array and its first element are different by printing sizeof array and sizeof array[0].

    0 讨论(0)
  • 2021-01-20 18:51

    The array variable signifies the entire memory block the array occupies, not only the array's first element. So array is not the same as array[0] (cf. sizeof array / sizeof array[0]). But the array's first element is located at the same memory address as the array itself.

    Saying the array points to the first element is also incorrect, in most circumstances, an array expression decays into a pointer to its first element, but they are different things (again cf. sizeof for example).

    0 讨论(0)
  • 2021-01-20 18:53
    char myChar = 'A'
    char msg[] = 'ABCDEFGH'
    

    When you type myChar you get value. But with msg you get pointer to first char(for values you have to use msg[x])

    msg = &msg[0]
    

    This can help you to understand, I think.

    0 讨论(0)
  • 2021-01-20 19:01

    In most circumstances, an expression of array type ("N-element array of T") will be replaced with / converted to / "decay" to an expression of pointer type ("pointer to T"), and the value of the expression will be the address of the first element in the array.

    So, assuming the declaration

    int a[10];
    

    the type of the expression a is "10-element array of int", or int [10]. However, in most contexts, the type of the expression will be converted to "pointer to int", or int *, and the value of the expression will be equivalent to &a[0].

    The exceptions to this rule are when the array expression is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration.

    So, based on our declaration above, all of the following are true:

      Expression   Type         Decays to     Value
      ----------   ----         ---------     -----
               a   int [10]     int *         address of the first element of a
              &a   int (*)[10]  n/a           address of the array, which is the
                                                same as the address of the first
                                                element
           &a[0]   int *        n/a           address of the first element of a
              *a   int          n/a           value of a[0]
        sizeof a   size_t       n/a           number of bytes in the array 
                                                (10 * sizeof (int))
       sizeof &a   size_t       n/a           number of bytes in a pointer to 
                                               an array of int
       sizeof *a   size_t       n/a           number of bytes in an int
    sizeof &a[0]   size_t       n/a           number of bytes in a pointer to int
    

    Note that the expressions a, &a, and &a[0] all have the same value (address of the first element of a), but the types are different. Types matter. Assume the following:

    int a[10];
    int *p = a;
    int (*pa)[10] = &a;
    

    Both p and pa point to the first element of a, which we'll assume is at address 0x8000. After executing the lines

    p++;
    pa++;
    

    however, p points to the next integer (0x8004, assuming 4-byte ints), while pa points to the next 10-element array of integers; that is, the first integer after the last element of a (0x8028).

    0 讨论(0)
  • 2021-01-20 19:04

    Look at it this way:

    &msg = 0x0012
    &msg[0] = 0x0012
    &msg[1] = 0x0013
    

    In this case &msg[1] is pointing to msg+1. When you reference &msg or &msg[0] you are referring to the same address of memory because this is where the pointer starts. Incrementing the array variable will increment the pointer by +1 since a char variable is only 1 byte in size.

    If you do the same trick with say an integer you will increment the pointer by +4 bytes since an integer is 4 bytes in size.

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