Сложение указателя против вычитания

$ 5.7 -

"[..] Для сложения оба операнда должны иметь арифметический или перечисляемый тип, - оба операнда имеют арифметический или перечислительный тип; или - оба операнда являются указателями на cv-квалифицированные или cv-неквалифицированные версии одного и того же полностью определенного типа объекта; или - левый операнд является указателем на полностью определенный тип объекта, а правый операнд имеет целочисленный или перечисляемый тип.

int main(){
        int buf[10];
        int *p1 = &buf[0];
        int *p2 = 0;

        p1 + p2;       // Error

        p1 - p2;       // OK
}

Итак, мой вопрос: , почему 'добавление указателя' не поддерживается в C ++, а 'указатель вычитание 'равно?

18
задан Chubsdad 30 August 2010 в 10:46
поделиться

5 ответов

Разница между двумя указателями означает количество элементов того типа, которые поместились бы между целями двух указателей. Сумма двух указателей означает... э... ничего, поэтому она не поддерживается.

30
ответ дан 30 November 2019 в 06:05
поделиться

Результатом вычитания является расстояние (полезно).

Результатом добавления указателя и расстояния является еще один осмысленный указатель.

Результатом добавления двух указателей является еще один указатель, но на этот раз бессмысленный.

По той же причине в большинстве библиотек существуют отдельные объекты TimeSpan и DateTime.

18
ответ дан 30 November 2019 в 06:05
поделиться

Первое, что приходит на ум, это то, что добавление указателя не имеет смысла, поэтому оно не поддерживается. Если у вас есть 2 указателя 0x45ff23dd, 0x45ff23ed. Что значит их добавить?? Некоторая память выходит за пределы допустимого. И люди в стандартном комитете не нашли достаточно веских причин для поддержки подобных вещей, а скорее предупреждают вас во время компиляции о возможной проблеме. В то время как вычитание указателя прекрасно, потому что оно указывает расстояние памяти, что часто бывает полезно.

4
ответ дан 30 November 2019 в 06:05
поделиться

Результатом вычитания указателя является количество объектов между двумя адресами памяти. Добавление указателя ничего не значит, поэтому оно не разрешено.

3
ответ дан 30 November 2019 в 06:05
поделиться

Потому что добавление двух указателей не имеет смысла.

Представьте, что у меня есть два int в памяти по адресам 0x1234 и 0x1240. Разница между этими адресами составляет 0xc и представляет собой расстояние в памяти. Сумма равна 0x2474 и не соответствует ничему значимому.

Однако можно добавить указатель к целому числу, чтобы получить другой указатель. Вот что вы делаете, когда индексируете массив: p[4] означает *(p + 4), что означает «вещь, хранящаяся по адресу, на 4 единицы дальше этого адреса».

В общем, вы можете определить « указатель" арифметической операции, присваивая каждому указателю значение 1 и каждому целому числу значение ноль.Если результат равен 1, у вас есть указатель; если это 0, у вас есть целое число; если это любое другое значение, у вас есть что-то, что не имеет смысла. Примеры:

/* here p,q,r are pointers, i,j,k are integers */
p + i; /* 1 + 0 == 1 => p+i is a pointer */
p - q; /* 1 - 1 == 0 => p-q is an integer */
p + (q-r); /* 1 + (1-1) == 1 => pointer */
2
ответ дан 30 November 2019 в 06:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: