Объявление переменных для семантически неотрицательных значений как unsigned
- это хороший стиль и хорошая практика программирования.
Однако имейте в виду, что это не мешает вам делать ошибки.Если это совершенно законно, присваивать отрицательные значения целым числам без знака, при этом значение неявно преобразуется в беззнаковую форму в соответствии с правилами арифметики без знака.Некоторые компиляторы могут выдавать предупреждения в таких случаях, другие будут делать это тихо.
Стоит также отметить, что работа с целыми числами без знака требует знания некоторых специальных методов без знака.Например, «классическим» примером, который часто упоминается в связи с этой проблемой, является обратная итерация
for (int i = 99; i >= 0; --i) {
/* whatever */
}
Вышеуказанный цикл выглядит естественно со знаком i
, но его нельзя напрямую преобразовать в беззнаковую форму,это означает, что
for (unsigned i = 99; i >= 0; --i) {
/* whatever */
}
на самом деле не делает то, что задумано (на самом деле это бесконечный цикл).Надлежащая техника в этом случае - либо
for (unsigned i = 100; i > 0; ) {
--i;
/* whatever */
}
, либо
for (unsigned i = 100; i-- > 0; ) {
/* whatever */
}
. Это часто используется в качестве аргумента против неподписанных типов, то есть якобы вышеупомянутые неподписанные версии цикла выглядят «неестественно».и "нечитаемый".В действительности, хотя проблема, с которой мы здесь имеем дело, это общая проблема работы около левого конца закрытого открытого диапазона.Эта проблема проявляется по-разному в C и C ++ (например, обратная итерация по массиву с использованием техники «скользящего указателя» обратной итерации по стандартному контейнеру с использованием итератора).То есть, независимо от того, насколько неприглядными могут выглядеть вышеприведенные циклы без знака, невозможно полностью их избежать, даже если вы никогда не используете целочисленные типы без знака.Таким образом, лучше изучить эти методы и включить их в свой набор установленных идиом.