int
состояли всего из 16 битов и каждый бит был на счету, функция-член v.size()
из класса vector возвращает целое число без знака.
vector
// ...
for (int i = 0; i
“Разумный” компилятор может предупредить, что мы смешиваем значения со знаком (т.е. переменную i
) и без знака (т.е., v.size()
). Такое смешение может привести к катастрофе. Например, счетчик цикла i
может оказаться переполненным; иначе говоря, значение v.size()
может оказаться больше, чем максимально большое число типа int
со знаком. В этом случае переменная i
может достигнуть максимально возможного положительного значения, которое можно представить с помощью типа int
со знаком (два в степени, равной количеству битов в типе int
, минус один, и еще раз минус один, т.е. 215–1). Тогда следующая операция ++
не сможет вычислить следующее за максимальным целое число, а вместо этого вернет отрицательное значение. Этот цикл никогда не закончится! Каждый раз, когда мы будем достигать максимального целого числа, мы будем начинать этот цикл заново с наименьшего отрицательного значения типа int
. Итак, для 16-битовых чисел типа int этот цикл содержит ошибку (вероятно, очень серьезную), если значение v.size()
равно 32*1024 или больше; для 32-битовых целых чисел типа int
эта проблема возникнет, только когда счетчик i
достигнет значений 2*1024*1024*1024.
vector
, либо итераторы.
for (vector
cout << v[i] << '\n';
for (vector
cout << *p << '\n';
Тип size_type
не имеет знака, поэтому первая форма целых чисел (без знака) имеет на один значащий бит больше, чем версия типа int, рассмотренная выше. Это может иметь значение, но следует иметь в виду, что увеличение происходит только на один байт (т.е. количество выполняемых операций может быть удвоено). Циклы, использующие итераторы, таких ограничений не имеют.
ПОПРОБУЙТЕ
Следующий пример может показаться безобидным, но он содержит бесконечный цикл:
void infinite()
{
unsigned char max = 160; // очень большое
for (signed char i=0; i
cout << int(i) << '\n';
}
Выполните его и объясните, почему это происходит.
+
, –
, *
и /
).
• Позволяет повысить точность на один бит.
• Позволяет отразить логические свойства целых чисел в ситуациях, когда они не могут быть отрицательными.
Из-за причин, указанных выше, программисты отказались от использования счетчиков цикла без знака.
unsigned int ui = –1;
int si = ui;
int si2 = ui+2;
unsigned ui2 = ui+2;