Search code examples
carrayspointerspointer-to-array

Array and Array[0] confusion


In the following C code:

char test[] ={'T','e','s','t'};

printf("%d\n",test == &test[0]); // Returns 1 - Okay as array varaible holds address of first element

So shouldn't the following should print the same?:

printf("value of test %c\n", test); // prints - '|' not even in the array
printf("value of test[0] %c\n", test[0]); // prints - 'T'

Not even that, even these prints different values:

printf("value of test %p\n", test); // contains a address 0x7ffee9b22b7c
printf("value of test[0] %p\n", test[0]); // also conatains 0x100

What is happening?

thanks


Solution

  • Pointer decay

    While pointers and arrays are different types of variables, the array variable is often implicitly converted as pointer to its first element. This is called array to pointer decay.

    This is what is happening in the comparison you make between test and &test[0]: test decays to a pointer which can be compared to &test[0], and their value are equal

    What is happening in your printf calls ?

    printf("value of test %c\n", test); // prints - '|' not even in the array
    printf("value of test[0] %c\n", test[0]); // prints - 'T'
    

    The first ones with the conversion specifier %c converts the argument to unsigned char and prints the character. In the first line you print test as a character and in the second line you print test[0] as a character.

    The type of test[0] is indeed a char so the correct character (the T) gets printed. However the type of test is an array of char, which in this case, also decays to a pointer. In your execution of the test this pointer happens have the value of 0x7ffee9b22b7c. This value is then converted to unsigned char so the last byte of your pointer is kept, in that case that's 7c which happens to be the ASCII code for character |.

    Note that since it depends on the value of the pointer it is very likely that you will get a different character printed every time you run the program (some of them might even not be printable characters).

    The two results are different because they are different things : one is a character and the other is a pointer (in this case a pointer to a character).

    test[0] is the value that is contained at the beginning of the array, while test is evaluated as a pointer to the first element (and then forcibly converted to a character). As you noted earlier, the test is equivalent to &test[0] and not to test[0].

    test[0] is equivalent to *test (or to *(test + 0)). In general in an array, array[i] will be equivalent to *(array +i).