Проблема с указателями и постфиксами
Поэтому я должен выяснить, почему распечатываются конкретные значения, и я решил большинство из них, но у меня возникла проблема с последними тремя.
Буду рад любой помощи
int main(void)
{
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
mess(&myValues[3]); //starts function mess
}
void mess(int *n)
{
printf("mess :%d\n", *n++); //prints value of 3rd index (1) and sets pointer to fourth index
printf("mess: %d\n", *++n); //sets n to 5th index and prints its value
printf("mess: %d\n", -2[n]); //value: -3
printf("mess: %d\n", (-2)[n]); //value: 1
printf("mess: %d\n", n[-6]); //value: 32766
}
Я просто не понимаю, как значения -3, 1 и 32766 становятся
3 ответа
Во-первых, давайте визуализируем память, на которую указывает n
после исполнения первых двух printf()
заявления:
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
^
// n
Давайте посмотрим один за другим
Заявление 1:
printf("mess: %d\n", -2[n]); //value: -3
Проверьте приоритет оператора.
-2[n]
анализируется как-(2[n])
, Таким образом-
это знак,2[n]
такой же какn[2]
что является ценностью3
, Таким образом, утверждение так же, какprintf("mess: %d\n", -(n[2]) );
Визуализация:
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 }; ^ ^^ // n n+2
Заявление 2:
printf("mess: %d\n", (-2)[n]); //value: 1
Вот,
n[-2]
такой же как*(n-2)
, Результатом является значение по этому индексу. (Проверьте приведенную выше визуализацию).Визуализация:
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 }; ^ ^ ^ // n-2 n n+2
Наконец, утверждение 3:
printf("mess: %d\n", n[-6]); //value: 32766
Согласно текущему содержанию указателя
n
наименее доступный индекс-5
, пытаясь получить доступ к ячейке памяти по индексу-6
доступ за пределы, вызывает неопределенное поведение. Результат не может быть оправдан.Визуализация:
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 }; ??? ^ ^ // n-6 n-5 n
printf("mess: %d\n", -2[n]); //value: -3
-2[n]
является -(n[2])
(см. здесь объяснение этой причуды). С этой точки зрения, n[2]
получает вас 3
так -n[2]
является -3
,
printf("mess: %d\n", (-2)[n]); //value: 1
Это [-2]
, что означает 2 слева от того, где вы начали, в результате чего 1
,
printf("mess: %d\n", n[-6]); //value: 32766
Это происходит до начала вашего массива, и это неопределенное поведение. Он может делать что угодно, но, скорее всего, он просто печатает какое-то мусорное значение, интерпретируя память, к которой у него нет доступа.
Я не уверен, насколько хорошо определены другие операторы кода. Это действительно плохая практика, пожалуйста, не пишите такой код. Как вы правильно сказали, это mess
,
Во-первых, помните, что в C индексация массива коммутативна - a[i]
а также i[a]
дать тот же результат.
Итак, линия
printf("mess: %d\n", -2[n]); //value: -3
эквивалентно письму
printf( "mess: %d\n", -n[2] );
Постфикс []
оператор имеет более высокий приоритет, чем унарный -
оператор, поэтому выражение -2[n]
анализируется как -(2[n])
, Вы индексируете 2 элемента из n
(3) и отрицание результата.
В следующей строке
printf("mess: %d\n", (-2)[n]); //value: 1
выражение (-2)[n]
эквивалентно n[-2]
- вы индексируете 2 элемента раньше n
, который дает вам 1.
В соответствии
printf("mess: %d\n", n[-6]); //value: 32766
вы пытаетесь проиндексировать 6 элементов, прежде чем n
; к сожалению, это за пределами вашего массива. На данный момент поведение не определено. Вы можете получить вывод мусора, сбой кода или что-то еще может произойти.