Распад указателя
Хотя указатели и массивы являются разными типами переменных, переменная массива часто неявно преобразуется как указатель на свой первый элемент. Это называется массив до затухания указателя .
Это то, что происходит в сравнении, которое вы проводите между test
и &test[0]
: test
распадается на указатель, который можно сравнить с &test[0]
, и их значение равно
Что происходит в ваших printf
вызовах?
printf("value of test %c\n", test); // prints - '|' not even in the array
printf("value of test[0] %c\n", test[0]); // prints - 'T'
Первые из них со спецификатором преобразования %c
преобразуют аргумент в unsigned char
и печатает символ. В первой строке вы печатаете test
как символ, а во второй строке вы печатаете test[0]
как символ.
Тип test[0]
действительно char
, поэтому правильный символ ( T
) печатается. Однако тип test
- это массив char
, который в этом случае также распадается на указатель. При выполнении теста этот указатель имеет значение 0x7ffee9b22b7c
. Затем это значение преобразуется в unsigned char
, поэтому последний байт вашего указателя сохраняется, в этом случае это 7c
, что является кодом ASCII для символа |
.
Обратите внимание, что, поскольку это зависит от значения указателя, очень вероятно, что вы будете получать разные символы при каждом запуске программы (некоторые из них могут даже не быть печатными символами).
Два результата отличаются, потому что это разные вещи: один - символ, а другой - указатель (в данном случае указатель на символ).
test[0]
- это значение он содержится в начале массива, а test
оценивается как указатель на первый элемент (а затем принудительно преобразуется в символ). Как вы отмечали ранее, test
эквивалентно &test[0]
, а не - test[0]
.
test[0]
эквивалентно *test
(или *(test + 0)
) , В общем случае в массиве array[i]
будет эквивалентно *(array +i)
.