Переписать для цикла эффективно, C - PullRequest
0 голосов
/ 26 июня 2011

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

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

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

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

Спасибо

Ответы [ 8 ]

10 голосов
/ 26 июня 2011
i = 0;
do {
  f(i);
} while(i++!=255);
5 голосов
/ 26 июня 2011

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

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

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

3 голосов
/ 26 июня 2011
uint8_t i = 0;
do {
    ...
} while ((++i) != 0);

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

1 голос
/ 26 июня 2011

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

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

1 голос
/ 26 июня 2011

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

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) при необходимости.

1 голос
/ 26 июня 2011

Я могу думать только о том, чтобы иметь логическое значение

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

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

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

0 голосов
/ 26 июня 2011

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

0 голосов
/ 26 июня 2011

РЕДАКТИРОВАТЬ: я неправильно понял, он зацикливается 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++)
...