Я запутался, как понимать этот код.содержит двойные указатели - PullRequest
0 голосов
/ 08 мая 2019

Я не понимаю, почему код ниже изменяет массив b:

int a[] = { 3, 6, 9 };
int b[] = { 2, 4, 6, 8, 10 };
int **c;
int **d[2];
c = (int **)malloc (b[1] * sizeof(int *));
*c = &a[1];
c[1] = c[0] + 1;
*d = c;
c = c + 2;
*c = b;
c[1] = &c[0][3];
*(d + 1) = c;
d[0][3][1] = d[1][0][0];
d[1][0][2] = d[0][1][0];

Я запустил этот код и нашел значения массива a и массива b, но яне в состоянии понять, как получаются эти значения.

Массив a остается неизменным, пока b становится 2, 4, 9, 8, 2.Как это произошло?

c = (int**)malloc(b[1] * sizeof(int*));  //int **c[4] ???

c - это массив двойных указателей *c = &a[1] это означает, что c[0] имеет адрес второго индекса массива a.Я не понимаю, как это интерпретировать.

1 Ответ

4 голосов
/ 08 мая 2019

Код содержит фактические операторы, поэтому он должен быть частью тела функции, поэтому все объявления в нем имеют автоматическое хранение. Это очень запутанный, с намеренно придуманными двойными косвениями ... Давайте проанализируем это по одной строке за раз:

  • int a[] = { 3, 6, 9 }; - a - это массив из 3-х точек, инициализированный с некоторыми явными значениями.

  • int b[] = { 2, 4, 6, 8, 10 }; - аналогично, b - это массив из 3-х целых чисел, инициализированный с некоторыми явными значениями.

  • int **c; - c - это неинициализированный указатель на указатель на int, который можно сделать так, чтобы он указывал на массив указателей на int.

  • int **d[2]; - d - это неинициализированный массив из 2 указателей на указатели на int, каждый из которых можно указать на массив указателей на int.

  • c = (int **)malloc(b[1] * sizeof(int *)); - c указывает на блок неинициализированной памяти с размером указателей 4 на int. Короче говоря, c теперь указывает на неинициализированный массив из 4 указателей на int.

  • *c = &a[1]; - элемент, на который указывает c (он же A[0]), устанавливается так, чтобы указывать на второй элемент a (он же a[1], со значением 6 ). Значение A[0] равно &a[1].

  • c[1] = c[0] + 1; - Второй элемент в массиве, на который указывает c (он же A[1]), должен указывать на элемент после того, на который указывает c[0], следовательно, он указывает на третий элемент a (он же a[2] со значением 9). Значение A[1] is & a [2] `.

  • *d = c; - Первый элемент d установлен на значение указателя c, который является адресом A[0]. Значение d[0] равно &A[0].

  • c = c + 2; - Указатель c увеличивается на 2, теперь он указывает на третий элемент массива A, выделенный с помощью malloc(), A[2].

  • *c = b; - Элемент, на который указывают c, A[2], который сам является указателем, устанавливается для указания на первый элемент b, b[0]. Значение A[2] равно &b[0].

  • c[1] = &c[0][3]; - Элемент после этого, A [3], 4-й элемент массива, выделенный malloc, устанавливается для указания на 4-й элемент массива, на который указывает элемент c указывает на. &c[0][3] эквивалентно c[0] + 3 или &(*c)[3] или просто *c + 3. Этот элемент b[3] имеет значение 8. Значение A[3] is & b [3] `.

  • *(d + 1) = c; - Это эквивалентно d[1] = c;, который устанавливает для второго элемента d значение указателя c, который является адресом третьего элемента массива, выделенного wth malloc(), A[2], что указывает на b[0]. Значение d[1] равно &A[2].

  • d[0][3][1] = d[1][0][0]; - Давайте перепишем эти термины:

    • d[0][3][1] => (& A [0]) [3] [1] => A[3][1] => (&b[3])[1] => *((b + 3) + 1) => b[4]

    • d[1][0][0] => (&A[2])[0][0] => (*&A[2])[0] => A[2][0] => (&b[0])[0] => b[0], что является значением 2.

    • Следовательно b[4] = 2;.

  • d[1][0][2] = d[0][1][0]; - Давайте перепишем это:

    • d[1][0][2] => (&A[2])[0][2] => (*&A[2])[2] => A[2][2] => (&b[0])[2] => (b + 0)[2] => b[2].
    • d[0][1][0] => (&A[0])[1][0], то есть A[1][0] => (&a[2])[0] => *&a[2] => a[2], значение которого 9.
    • Следовательно b[2] = 9;

Как следствие, массив b теперь содержит элементы { 2, 4, 9, 8, 2 }.

Вы можете запустить программу:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int a[] = { 3, 6, 9 };
    int b[] = { 2, 4, 6, 8, 10 };
    int **c;
    int **d[2];
    c = (int **)malloc (b[1] * sizeof(int *));
    *c = &a[1];
    c[1] = c[0] + 1;
    *d = c;
    c = c + 2;
    *c = b;
    c[1] = &c[0][3];
    *(d + 1) = c;
    d[0][3][1] = d[1][0][0];
    d[1][0][2] = d[0][1][0];

    printf("a = { ");
    for (size_t i = 0; i < sizeof a / sizeof *a; i++)
        printf("%d, ", a[i]);
    printf("};\n");

    printf("b = { ");
    for (size_t i = 0; i < sizeof b / sizeof *b; i++)
        printf("%d, ", b[i]);
    printf("};\n");

    return 0;
}

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