должен ли этот пример не изменять адрес памяти, а не значение в этом адресе памяти?

В книге, которую я читаю, C ++ с нуля, на странице 113 автор создает массив символов:

myString[80];

Затем он использует функцию, которая копирует некоторые символы:

strcpy(myString,"Hello there");

Затем он создает указатель на массив:

*p1 = myString;

затем он использует смещение и присваивает значение этому смещению:

p1[4]='c';

мой вопрос, p1 является указателем, так что это адрес памяти, а смещение 4 дает ему адрес памяти на 4 пробела впереди, так что это означает, что он вводит букву ‘c’ в адрес памяти, а не в значение хранится по этому адресу. Не должно ли это быть:

*(p1[4])='c';

в общем, почему * (p1 + 4) нуждается в разыменовании, а p1 [4] — нет?

Я пытался понять это, и единственное, что могло иметь для меня смысл, — это если квадратные скобки действуют как звездочка для разыменования указателя. Это правильно или есть другая причина, почему p1 [4] не нужно разыменовывать?

0

Решение

Затем он создает указатель на массив:

*p1 = myString;

Предполагая, что под этим вы на самом деле имеете в виду, что p1 объявляется и инициализируется с помощью;

char *p1 = myString;

тогда ваша интерпретация неверна. p1 это указатель на char не указатель на массив.

В этом определении myString является (ранее объявленным в вашем вопросе) именем массива char, В инициализации

char *p1 = myString;

имя myString преобразуется в указатель Этот указатель будет иметь значение &myString[0] (то есть адрес первого символа в myString). Это значение, которое p1 получит.

Заявление

 p1[4] = 'c';

затем установит пятый символ (поскольку индексация начинается с нуля) myString быть 'c', Поэтому результат меняется myString[4] к стоимости 'c', Это означает, что (первые 11 символов) myString будет "Hellc there",

Исходя из вышесказанного, выражение *(p1[4])='c' не будет компилироваться, т.к. (p1[4]) имеет тип charи не может быть разыменовано с помощью * оператор.

Семантически, в выражении p1[4] эквивалентно *(p1 + 4), поскольку p1 инициализируется равным &myString[0], p1[4] ТАКЖЕ эквивалентно обоим myString[4] и к *(myString + 4),

Замечания: Если *(p1[4])='c' был действителен в вашем коде, то p1[4] = 'c' не будет действительным, что предполагает мое предположение об объявлении и инициализации p1 правильно — несмотря на то, что вы пропустили такую ​​информацию.

3

Другие решения

p1 + 4 будет адрес памяти в 4 местах.

Выражение p1[4] (точно эквивалентно *(p1+4)) называется именующий выражение. Мы говорим, что выражение lvalue назначает в ячейка памяти. Или, другими словами, выражение lvalue является синонимом самой ячейки памяти. Вы всегда можете использовать & оператор адреса в выражении lvalue, и это дает вам указатель на ячейку памяти.

Выражение lvalue будет использоваться одним из трех возможных способов:

  1. Сохраните значение в указанном месте памяти, или
  2. Получить значение из назначенной ячейки памяти или
  3. Ни один из тех.

Не существует специального синтаксиса, чтобы различать эти три случая; скорее это зависит от большего выражения, частью которого является выражение lvalue. Например, применяя & оператор — это случай 3; появляется в левой части оператора присваивания = это случай 1. Большинство других видов использования подпадают под случай 2.

0

p1[4] рассматривается как *(p1 + 4) который является «значением по смещению 4 от p1».

Также, когда вы объявляете массив символов:

myString[80]

myString — указатель на массив (он указывает на первый элемент). Итак, когда вы делаете myString[4] это также рассматривается как *(myString + 4)

Пишу *(p1[4]) будет означать *(*(p1 + 4))

-3
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector