Переписать для цикла эффективно, C
Я хочу использовать байтовую переменную i
выполнить немного кода 256 раз. Строка ниже зацикливается бесконечно, есть ли аккуратная альтернатива, которая будет работать?
for (i = 0; i < 255; i++){
Надеюсь, без использования:
- 16-битная переменная (или любые дополнительные биты вообще)
- вложенные циклы
while(1)
break;
заявления
Спасибо
8 ответов
Всегда мог сделать это:
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
но это не так.