Ответ 1
Строковые литералы существуют в сегменте фиксированных данных программы, поэтому они отображаются компилятором как тип указателя.
+-+-+-+-+-+--+
|1|2|3|4|5|\0|
+-+-+-+-+-+--+
^ MY_STRING
^ MY_STRING + 2
Я видел это на C раньше:
#define MY_STRING "12345"
...
#define SOMETHING (MY_STRING + 2)
ЧТО ЧТОБЫ ОБРАТИТЬСЯ, здесь? Это даже законно? Или они имеют в виду это?:
#define SOMETHING (MY_STRING[2])
Строковые литералы существуют в сегменте фиксированных данных программы, поэтому они отображаются компилятором как тип указателя.
+-+-+-+-+-+--+
|1|2|3|4|5|\0|
+-+-+-+-+-+--+
^ MY_STRING
^ MY_STRING + 2
Когда у вас есть массив или указатель, p+x
эквивалентен &p[x]
. Таким образом, MY_STRING + 2
эквивалентно &MY_STRING[2]
: он дает адрес третьего символа в строке.
Обратите внимание, что происходит, когда вы добавляете 0. MY_STRING + 0
совпадает с &MY_STRING[0]
, оба из которых такие же, как просто запись MY_STRING
, поскольку строковая ссылка является не чем иным, как указателем на первый символ в строка. К счастью, тогда операция идентификации "добавить 0" является не-оператором. Считайте это своего рода умным unit test, который мы можем использовать, чтобы проверить, что наша идея о том, что означает +
, верна.