Неожиданное значение при обращении к указателю - PullRequest
1 голос
/ 15 апреля 2020

Я играю с OnlineGDB компилятором, чтобы понять, как работают указатели в C. Во-первых, я запустил следующий код и получил ожидаемый вывод:

int *array1[] = {1,4,3,4};

int main()
{
    printf("%d \n", array1[0+1]);
    printf("%d", array1[1+1]);

    return 0;
}

Вывод был: 4 3

Во-вторых, я запустил следующий код - и я не могу понять его вывод :

int *array1[] = {1,4,3,4};

int main()
{
    printf("%d \n", array1[0]+1);
    printf("%d", array1[1]+1);

    return 0;
}

Вывод: 5 8

Кажется, я добавляю 4 к значению из массива, но почему? (каждый элемент в массиве состоит из байта).

Спасибо!

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Кажется, я добавляю 4 к значению из массива, но почему?

Нет, каждый элемент массива является int *, потому что вы объявили массив таким образом:

int *array1[] = {1,4,3,4};

То есть array1 - это массив, значения которого имеют указатель типа на int. Удалите *, если вам нужен массив int, например:

int array1[] = {1,4,3,4};

Когда вы добавляете или вычитаете из типов указателей, значение изменяется в несколько раз больше размера типа, указанного указателем. относится к. Значение int в вашей системе, вероятно, составляет 4 байта, поэтому выражение типа array1[0]+1 получает int *, сохраненное в array[0], и увеличивает его, так что оно увеличивается на sizeof(int).

(каждый элемент в массиве состоит из байта).

Даже если вы объявили свой массив как массив int, а не как массив int *, размер из int, вероятно, не 1 байт. int обычно имеет длину 4 байта, но размер зависит от компилятора и целевой системы.

1 голос
/ 15 апреля 2020

С

int *array1[] = {1,4,3,4};

вы определяете массив tan из указателей на целые числа .

Таким образом, каждый элемент этого массива, даже если инициализируется с тем, что выглядит как целочисленные значения, на самом деле указатели , которые являются адресами.

Если бы вы указали эти указатели, вы, вероятно, вызвали бы ошибку сегментации. Но, к счастью, вы просто распечатали их, даже если использовали %d вместо %p: выбор, который в соответствии со стандартом C мог вызвать неопределенное поведение. В любом случае, в вашем случае указатели были преобразованы в целые числа, а напечатанные значения были ожидаемыми. Точно так же, как если бы массив был массивом целых чисел .

Во втором примере вы продвинули его дальше: вы добавили 1 к элементам массива . Но поскольку они являются указателями, то применяется арифметика указателей . Это означает, что указатель + N = указатель + N * sizeof (* указатель) . В этом случае, поскольку sizeof(int) равно 4:

array[0] + 1 =

= 1 + sizeof (array[0]) =

= 1 + sizeof( int ) =

= 1 + 4 = 5

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