В C и C ++ size_t
- это тип без знака, который используется для выражения размера. Он выражает намерение и несколько упрощает утверждения диапазона (len < upper_bound
против len >= 0 && len < upper_bound
для целых чисел со знаком).
(Во всех приведенных ниже примерах len
означает длину массива a
).
Идиома для l oop: for (i = 0; i < len; i++)
. Идиома отсталого для l oop - for (i = len-1; i >= 0; i--)
. Но наличие беззнаковых индексов l oop приводит к тонким ошибкам, и время от времени я путаю крайние случаи.
Во-первых, обратная сторона для l oop. Этот код ниже для len = 0.
for (size_t i = len-1; i >= 0; i--) { // Bad: Underflows for len=0
use(a[i]);
}
Есть трюк с оператором -->
, который выглядит странно, если вы к нему не привыкли.
for (size_t i = len; i--> 0;) {
use(a[i]);
}
Вы можете используйте тип со знаком для индексной переменной l oop, но он переполняется, если len > INT_MAX
. Многие люди и организации считают этот риск настолько минимальным, что они просто придерживаются int
.
for (int i = len-1; i >= 0; i--) { // BAD: overflows for len < INT_MAX
use(a[i]);
}
Так что я согласился на эту конструкцию, так как она наиболее близка к канонической для-l oop форме и имеет самые простые выражения.
for (size_t i = len; i > 0; i--) {
size_t pos = i-1;
use(a[pos]);
}
Моя проблема с итерацией от 0
до len-1
То есть с циклическим изменением диапазона [0, len-1). Это l oop понижается, когда len=0
.
for (size_t i = 0; i < len-1; i++) { // BAD: Underflows for len=0.
use(a[i]);
}
. Что касается случая итерации в обратном направлении, вы можете использовать целые числа со знаком, но это может вызвать переполнение.
for (int i = 0; i < len-1; i++) { // BAD: Will overflow if len > INT_MAX
use(a[i]);
}
Я склонен к добавьте еще одно выражение к условию l oop, проверяя на len > 0
, но это кажется неуклюжим.
for (size_t i = 0; len > 0 && i < len-1; i++) {
use(a[i]);
}
Я могу добавить оператор if перед l oop, но это также кажется неуклюжим.
Есть ли менее громоздкий способ записи для l oop с индексными переменными без знака, циклически изменяющимися от 0 до len-1?