Проблема с указателями и постфиксами

Поэтому я должен выяснить, почему распечатываются конкретные значения, и я решил большинство из них, но у меня возникла проблема с последними тремя.

Буду рад любой помощи

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; к сожалению, это за пределами вашего массива. На данный момент поведение не определено. Вы можете получить вывод мусора, сбой кода или что-то еще может произойти.

Другие вопросы по тегам