Предполагая определение:
int i = 10;
int *p = &i;
Почему здесь * p действительное значение lvalue:
*p+=10;
Не следует * p оценивать значение int, хранящегося в & i, т.е. 10, и, следовательно, генерировать ошибку "Not lvalue"?
Предполагая определение:
int i = 10;
int *p = &i;
Почему здесь * p действительное значение lvalue:
*p+=10;
Не следует * p оценивать значение int, хранящегося в & i, т.е. 10, и, следовательно, генерировать ошибку "Not lvalue"?
lvalue - выражение, которое относится к области который можно манипулировать.
*p
- это такое выражение, которое относится к области хранения. Это отличается от 10+=10;
, потому что 10
не относится к области хранения, такой как переменная.
Я считаю, что вы смущены определением p
. p
является, по сути, переменной указателя типа на int, а его значение инициализируется адресом i
.
Тем не менее, *p
также является допустимым значением l - допустимым выражением для места хранения.
В очень простых словах указатели указывают на объект (в общем смысле, не на ООП), а не на содержимое этого объекта. Итак, да, разыменованный указатель - это допустимое значение lvalue.
В условиях очень низкого уровня. Указатель - это не что иное, как адрес памяти, разыменованный указатель - это память по этому адресу.
Не следует
*p
оценивать значение int, хранящегося в&i
, т.е. 10, и, следовательно, генерировать ошибку "Not lvalue"?
Простыми словами,
*
означает "значение по адресу".
*p
означает "значение по адресу, заданному значением p
".
*p = 10;
означает "установить 10 в качестве значения по адресу, заданному значением p
".
lvalue - это выражение, которое ссылается на объект, хранящийся где-то в памяти. *p
также является выражением, которое относится к объекту, хранящемуся в местоположении p
.
Семантика
...
- Унарный оператор
*
обозначает косвенность. Если операнд указывает на функцию, результат будет обозначать функцию; , если он указывает на объект, результатом является lvalue, обозначающий объект. Если операнд имеет тип '' указатель на тип '', результат имеет тип '' type ''. Если для указателя присвоено недопустимое значение, поведение унарного оператора*
равно undefined
т.е. с
int i = 10;
int *p = &i;
результатом *p
является значение l, которое обозначает объект i
.
Поэтому *p += 10
работает, так как это lvalue.
Теперь, если lvalue используется в контексте, где сам объект необходим, он будет преобразован в значение, сохраненное в указанном объекте. Это называется преобразованием lvalue, и полученное значение, конечно, больше не является lvalue (C11 6.3.2.1p2).