Добро пожаловать в арифметику указателей.
char *name = "hello";
name
- указатель на символ. В нем хранится адрес "hello"
строкового литерала, т.е. адрес символа h
(адрес массива равен (значению) адресу первого элемента массива). Обратите внимание, что строковые литералы неизменны, вы не можете их изменять. Поэтому лучше всего изменить тип на const char*
.
&name
Это указатель на имя переменной. Не указатель на строковый литерал "hello"
, а указатель на указатель. 003EFAA4
является адресом переменной name
. Переменная была размещена компилятором в стеке внутри функции main()
.
*(&name)
Правило *&
(здесь) само собой. Так что *&name
равно name
. Это печатает значение указателя name
, т.е. это указатель на "hello"
строковый литерал, т.е. это указатель на символ h
внутри "hello"
строкового литерала. Не &name
. Адрес h
символа.
&name + 1
&name
имеет тип char **
, т.е. это как указатель на указатель на символ. Из арифметики указателей &name + 1
равно значению (uintptr_t)&name + 1 * sizeof(*&name)
. sizeof(*&name)
это sizeof(name)
это sizeof(char*)
, поэтому (uintptr_t)&name + sizeof(char*)
. В вашей архитектуре sizeof(char*)
составляет 4 байта (32-битная система?), Поэтому указатель увеличивается на 4. Т.е. 003EFAA4 + 4 = 003EFAA8
.
name + 1
name
имеет тип char*
. Из арифметики указателя name + 1
равно (uintptr_t)name + sizeof(*name)
. sizeof(*name)
- это sizeof(char)
. sizeof(char)
определено равным 1. Это печатает адрес e
символ внутри "hello"
строкового литерала.
&name + sizeof name
&name
имеет тип char**
, поэтому значение &name
увеличивается sizeof(name) * sizeof(char*) times. As
sizeof (имя) is equal to
sizeof (char *) , this is
sizeof (char *) * sizeof (char *) ie.
4 * 4 = 16` на вашем компьютере.
name + sizeof name
Это увеличивает значение указателя name
на значение sizoef(name) * sizeof(char)
. sizeof(name)
- это sizeof(char*)
- 4
в вашей архитектуре, sizeof(char)
- 1. Итак, name + sizeof name
- это адрес символа o
внутри "hello"
строкового литерала, т.е. 003EFAA8
.
@ edit переписать некоторые части