Проблема с указателями и постфиксами - PullRequest
0 голосов
/ 04 января 2019

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

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

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 ]

0 голосов
/ 04 января 2019

Сначала давайте визуализируем память, на которую указывает 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
    
0 голосов
/ 04 января 2019

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

0 голосов
/ 04 января 2019
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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...