Переписать для цикла эффективно, C

Я хочу использовать байтовую переменную i выполнить немного кода 256 раз. Строка ниже зацикливается бесконечно, есть ли аккуратная альтернатива, которая будет работать?

for (i = 0; i < 255; i++){

Надеюсь, без использования:

  • 16-битная переменная (или любые дополнительные биты вообще)
  • вложенные циклы
  • while(1)
  • break; заявления

Спасибо

8 ответов

Решение
i = 0;
do {
  f(i);
} while(i++!=255);

Всегда мог сделать это:

for (i = 0; i != 255; ++i)
{
    f(i);
}
f(255);

Честно говоря, вам лучше всего использовать int, Это не будет быстрее, если вы используете 8-битное целое число. Это будет в любом случае в реестре.

uint8_t i = 0;
do {
    ...
} while ((++i) != 0);

Конечно, предполагается, что i переполнится. Это не гарантируется стандартом C, но почти всегда происходит, когда компилятор не слишком оптимизирует.

Я бы сказал, что развертывание цикла было бы самым очевидным выходом из этого:

uint8_t i = 0;
for ( i = 0; i < 32; i++ )
{
    printf("Instance of loop %d\n", (8*i)+0);
    printf("Instance of loop %d\n", (8*i)+1);
    printf("Instance of loop %d\n", (8*i)+2);
    printf("Instance of loop %d\n", (8*i)+3);
    printf("Instance of loop %d\n", (8*i)+4);
    printf("Instance of loop %d\n", (8*i)+5);
    printf("Instance of loop %d\n", (8*i)+6);
    printf("Instance of loop %d\n", (8*i)+7);
}

Теоретически, это также должно быть быстрее, так как у вас меньше тестов и прыжков. Вы можете развернуть более строго, чем это тоже, если это необходимо.

Возможно, вас также заинтересует устройство Даффа (так объясняет его вопрос), которое позволит вам развернуть петлю любого размера, а не только одну с хорошими факторами. Конечно, существуют ограничения, так как для этого необходимо хранить в памяти количество того, что вам нужно, что в этом случае превышает 8-битное поле, но для циклических операций, скажем, 137 раз, это пригодится.

Обратите внимание, что вам не нужно делать 8*i+1 этапы, это просто чтобы убедиться, что произошло достаточно событий.

Еще одно замечание: "но я не хочу писать свой код 8 раз!" можно преодолеть с помощью inline функции (C99) или макросы (C89) при необходимости.

Единственный способ, которым я могу думать, это иметь логическое значение

b = 1;
for(i = 0; i != 0 || b; i++)
{
    b = 0;
    ...
}

Или вы могли бы использовать короткое, которое в 2 раза больше байта.

Происходит следующее: максимальное значение байта без знака равно 255. Я не уверен, что происходит с байтами без знака, но байты со знаком становятся отрицательными при переполнении.

Если "байт" char это всегда будет <255 в системах, где char подписан (и 8 бит). Если вы должны использовать тип "байт", попробуйте unsigned char, который должен работать для вашего цикла.

Если это не просто эксперимент, используйте int вместо.

РЕДАКТИРОВАТЬ: я не так, он зацикливается 255 раз...:) Лучше сделать конструкцию do-while:

  i = 0;
  do {
     // act
     i++;
  } while(i > 0);

Следующие два фрагмента повторяются 255 раз, от 1 до 255.

  for(i = 1; i <= 255 && i != 0; i++)

должны идти. Или, может быть

   for(i = 1; i > 0; i++)

В общем, быстрее всего будет объявить i как int, Я не могу себе представить, почему вы хотите зациклить с 8-битным целым числом. Возможно, вы думаете, что это будет быстрее, чем int но это не так.

Другие вопросы по тегам