История изменений
Исправление bormant, (текущая версия) :
Вот только в жизни бывает обычно по другому...
Эти тривиальные вопросы — они были не совсем просто так.
В паскалях программист во всех случаях, когда необходимо пройти по [a; b] (знаковых, беззнаковых) на автомате пишет примерно один и тот же код:
for i:=a to b do {...} ;
Для примера выше (доверять пользовательскому вводу нельзя, но не суть)
var
a, b, t: LongWord;
i: Integer;
begin
if ParamCount<2 then Halt(1);
Val(a,ParamStr(1),i); if i<>0 then Halt(2);
Val(b,ParamStr(2),i); if i<>0 then Halt(3);
if a>b then begin
t:=a; a:=b; b:=t;
end;
for t:=a to b do Write(' ',t);
for t:=b to a do Write(' ',t);
WriteLn;
end.
В Си для знаковых просто и удобно когда пределы константы:
for (int i=0; i<10; ++i)
printf(" %d",i);
for (int i=9; i>=0; --i)
printf(" %d",i);
но стоит вместо пределов получить переменные, где не исключено граничное значение диапазона, и, упс, нужно писать цикл иначе. Стоит изменить знаковые на беззнаковые, и упс, нужно писать цикл иначе.
А теперь скажите честно, сколько раз вы сами для итерации писали циклы как в этом тривиальном примере вместо for? А сколько раз копипастили циклы? Вот то-то и оно...
Вот такая вот провокация от языка ;-) Не смертельно, но неприятно, принцип наименьшего удивления никто не отменял.
К слову сказать, и для граничных значений, и для беззнаковых for(;;) тоже вполне применим, правда выглядит это несколько «нестандартно»:
for (unsigned i = a-1; a++ != b;) printf(" %u",i);
for (unsigned i = a+1; a-- != b;) printf(" %u",i);
Небольшой тест:
#include <stdio.h>
int main(int argc, char* argv[])
{
unsigned int a, b;
a=0; b=1;
for (unsigned int i = a-1; a++ != b;) printf(" %u"); printf("\n");
a=1; b=0;
for (unsigned int i = a+1; a-- != b;) printf(" %u"); printf("\n");
a=0xfffffffe; b=0xffffffff;
for (unsigned int i = a-1; a++ != b;) printf(" %u"); printf("\n");
a=0xffffffff; b=0xfffffffe;
for (unsigned int i = a+1; a-- != b;) printf(" %u"); printf("\n");
}
Часто вы такие циклы в живом коде видите или сами пишете ;-) ?
Исправление bormant, :
Вот только в жизни бывает обычно по другому...
Эти тривиальные вопросы — они были не совсем просто так.
В паскалях программист во всех случаях, когда необходимо пройти по [a; b] (знаковых, беззнаковых) на автомате пишет примерно один и тот же код:
for i:=a to b do {...} ;
Для примера выше (доверять пользовательскому вводу нельзя, но не суть)
var
a, b, t: LongWord;
i: Integer;
begin
if ParamCount<2 then Halt(1);
Val(a,ParamStr(1),i); if i<>0 then Halt(2);
Val(b,ParamStr(2),i); if i<>0 then Halt(3);
if a>b then begin
t:=a; a:=b; b:=t;
end;
for t:=a to b do Write(' ',t);
for t:=b to a do Write(' ',t);
WriteLn;
end.
В Си для знаковых просто и удобно когда пределы константы:
for (int i=0; i<10; ++i)
printf(" %d",i);
for (int i=9; i>=0; --i)
printf(" %d",i);
но стоит вместо пределов получить переменные, где не исключено граничное значение диапазона, и, упс, нужно писать цикл иначе. Стоит изменить знаковые на беззнаковые, и упс, нужно писать цикл иначе.
А теперь скажите честно, сколько раз вы сами для итерации писали циклы как в этом тривиальном примере вместо for? А сколько раз копипастили циклы? Вот то-то и оно...
Вот такая вот провокация от языка ;-) Не смертельно, но неприятно, принцип наименьшего удивления никто не отменял.
К слову сказать, и для граничных значений, и для беззнаковых for(;;) тоже вполне применим, правда выглядит это несколько «нестандартно»:
for (unsigned i = a-1; a++ != b;) printf(" %u",i);
for (unsigned i = a+1; a-- != b;) printf(" %u",i);
Небольшой тест:
#include <stdio.h>
int main(int argc, char* argv[])
{
unsigned int a, b;
a=0; b=1;
for (unsigned int i = a-1; a++ != b;) printf(" %u"); printf("\n");
a=1; b=0;
for (unsigned int i = a+1; a-- != b;) printf(" %u"); printf("\n");
a=0xfffffffe; b=0xffffffff;
for (unsigned int i = a-1; a++ != b;) printf(" %u"); printf("\n");
a=0xffffffff; b=0xfffffffe;
for (unsigned int i = a+1; a-- != b;) printf(" %u"); printf("\n");
}
Часто вы такие циклов в живом коде видите или сами пишете ;-) ?
Исходная версия bormant, :
Вот только в жизни бывает обычно по другому...
Эти тривиальные вопросы — они были не совсем просто так.
В паскалях программист во всех случаях, когда необходимо пройти по [a; b] (знаковых, беззнаковых) на автомате пишет примерно один и тот же код:
for i:=a to b do {...} ;
Для примера выше (доверять пользовательскому вводу нельзя, но не суть)
var
a, b, t: LongWord;
i: Integer;
begin
if ParamCount<2 then Halt(1);
Val(a,ParamStr(1),i); if i<>0 then Halt(2);
Val(b,ParamStr(2),i); if i<>0 then Halt(3);
if a>b then begin
t:=a; a:=b; b:=t;
end;
for t:=a to b do Write(' ',t);
for t:=b to a do Write(' ',t);
WriteLn;
end.
В Си для знаковых просто и удобно когда пределы константы:
for (int i=0; i<10; ++i)
printf(" %d",i);
for (int i=9; i>=0; --i)
printf(" %d",i);
но стоит вместо пределов получить переменные, где не исключено граничное значение диапазона, и, упс, нужно писать цикл иначе. Стоит изменить знаковые на беззнаковые, и упс, нужно писать цикл иначе.
А теперь скажите честно, сколько раз вы сами для итерации писали циклы как в этом тривиальном примере вместо for? А сколько раз копипастили циклы? Вот то-то и оно...
Вот такая вот провокация от языка ;-) Не смертельно, но неприятно, принцип наименьшего удивления никто не отменял.
К слову сказать, и для граничных значений, и для беззнаковых for(;;) тоже вполне применим, правда выглядит это несколько «нестандартно»:
for (unsigned i = a-1; a++ != b;) printf(" %u",i);
for (unsigned i = a+1; a-- != b;) printf(" %u",i);
Небольшой тест:
#include <stdio.h>
int main(int argc, char* argv[])
{
unsigned int a, b;
a=0; b=1;
for (unsigned int i = a-1; a++ != b;) printf(" %u"); printf("\n");
a=1; b=0;
for (unsigned int i = a+1; a-- != b;) printf(" %u"); printf("\n");
a=0xfffffffe; b=0xffffffff;
for (unsigned int i = a-1; a++ != b;) printf(" %u"); printf("\n");
a=0xffffffff; b=0xfffffffe;
for (unsigned int i = a+1; a-- != b;) printf(" %u"); printf("\n");
}
Часто вы такие циклов в живом коде видите или сами пишете ;-) ?