LINUX.ORG.RU

История изменений

Исправление 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");
}

Часто вы такие циклов в живом коде видите или сами пишете ;-) ?