огласите весь список, пожалуйстаConst14 писал(а):Многие компиляторы
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
огласите весь список, пожалуйстаConst14 писал(а):Многие компиляторы
Код: Выделить всё
#include <avr/io.h>
int main(void){
uint8_t i;
// вариант 1 - 106 байт flash
i = 12;
while(i--){
PORTB = PINC;
}
// вариант 2 - 104 байта flash
for(i = 12; i; i--){
PORTB = PORTC;
}
// вариант 3 - 104 байта flash
i = 12;
do{
PORTB = PORTC;
i--;
} while(i);
}Не "лучше", а "необходимо" !Const14 писал(а):Но пользоваться лучше тем, который больше подходит для данного конкретного случая
Код: Выделить всё
do{}while();
Код: Выделить всё
while(){}
Код: Выделить всё
for(;;){}
циклы while и for обладают тем приятным свойством, что в них проверка окончания осуществляется в начале, а не в конце цикла. Третий оператор цикла языка C, do-while, проверяет условие окончания в конце, после каждого прохода через тело цикла; тело цикла всегда выполняется по крайней мере один раз.
Как и можно было ожидать, цикл do-while используется значительно реже, чем while и for, составляя примерно пять процентов от всех циклов. Тем не менее, иногда он оказывается полезным, как, например, в следующей функции itoa, которая преобразует число в символьную строку (обратная функции atoi). Эта задача оказывается несколько более сложной, чем может показаться сначала. Дело в том, что простые методы выделения цифр генерируют их в неправильном порядке. Мы предпочли получить строку в обратном порядке, а затем обратить ее.
Код: Выделить всё
/* конвертировать n в строку s */
itoa(n, s)
char s[];
int n;
{
int i, sign;
if((sign = n) < 0) /* сохранить знак */
n = -n; /* сделать n положительным */
i = 0;
do { /* генерируем цифры в обратном порядке */
s[i++] = n % 10 + '0'; /* получить следующую цифру */
} while((n /= 10) > 0); /* удалить ее */
if(sign < 0)
s[i++] = '-'
s[i] = '\0';
reverse(s);
}Цикл do-while здесь необходим, или по крайней мере удобен, поскольку, каково бы ни было значение n, массив s должен содержать хотя бы один символ. Мы заключили в фигурные скобки один оператор, составляющий тело do-while, хотя это и не обязательно, для того, чтобы торопливый читатель не принял часть while за начало оператора цикла while.
ну приведите аналогичный тест частного случая, подтверждающего ваше утверждение - в чем проблема?Const14 писал(а):вы привели частный пример задачи, решаемой с помощью трёх типов цикла, я расписал общий случай.
Код: Выделить всё
unsigned char a,b,c;
//----------------------
void f1(void)
{
c = 0;
do
{
c += b;
b++;
}while( a>b );
}
void f2(void)
{
c=0;
while( a>b )
{
c += b;
b++;
}
}
void f3(void)
{
for( c=0; a>b; b++ )
{
c += b;
}
}
//----------------------
void main(void)
{
a = 10;
b = 2;
f1();
//---------
a = 10;
b = 2;
f2();
//---------
a = 10;
b = 2;
f3();
}
Код: Выделить всё
;
; void f1(void)
;
assume cs:_TEXT
_f1 proc near
push bp
mov bp,sp
;
; {
; c = 0;
;
mov byte ptr DGROUP:_c,0
@1@58:
;
; do
; {
; c += b;
;
mov al,byte ptr DGROUP:_b
add byte ptr DGROUP:_c,al
;
; b++;
;
inc byte ptr DGROUP:_b
;
; }while( a>b );
;
mov al,byte ptr DGROUP:_a
cmp al,byte ptr DGROUP:_b
ja short @1@58
;
; }
;
pop bp
ret
_f1 endp
;
; void f2(void)
;
assume cs:_TEXT
_f2 proc near
push bp
mov bp,sp
;
; {
; c=0;
;
mov byte ptr DGROUP:_c,0
jmp short @2@86
@2@58:
;
; while( a>b )
; {
; c += b;
;
mov al,byte ptr DGROUP:_b
add byte ptr DGROUP:_c,al
;
; b++;
;
inc byte ptr DGROUP:_b
@2@86:
mov al,byte ptr DGROUP:_a
cmp al,byte ptr DGROUP:_b
ja short @2@58
;
; }
; }
;
pop bp
ret
_f2 endp
;
; void f3(void)
;
assume cs:_TEXT
_f3 proc near
push bp
mov bp,sp
;
; {
; for( c=0; a>b; b++ )
;
mov byte ptr DGROUP:_c,0
jmp short @3@114
@3@58:
;
; {
; c += b;
;
mov al,byte ptr DGROUP:_b
add byte ptr DGROUP:_c,al
inc byte ptr DGROUP:_b
@3@114:
mov al,byte ptr DGROUP:_a
cmp al,byte ptr DGROUP:_b
ja short @3@58
;
; }
; }
;
pop bp
ret
_f3 endp
Код: Выделить всё
;------------------------------------------------------------
;Allocation info for local variables in function 'f1'
;------------------------------------------------------------
; 8051test.c:6: void f1(void)
; -----------------------------------------
; function f1
; -----------------------------------------
_f1:
ar7 = 0x07
ar6 = 0x06
ar5 = 0x05
ar4 = 0x04
ar3 = 0x03
ar2 = 0x02
ar1 = 0x01
ar0 = 0x00
; 8051test.c:8: c = 0;
mov _c,#0x00
; 8051test.c:9: do
00101$:
; 8051test.c:11: c += b;
mov a,_b
add a,_c
mov _c,a
; 8051test.c:12: b++;
inc _b
; 8051test.c:13: }while( a>b );
clr c
mov a,_b
subb a,_a
jc 00101$
ret
;------------------------------------------------------------
;Allocation info for local variables in function 'f2'
;------------------------------------------------------------
; 8051test.c:16: void f2(void)
; -----------------------------------------
; function f2
; -----------------------------------------
_f2:
; 8051test.c:18: c=0;
mov _c,#0x00
; 8051test.c:19: while( a>b )
00101$:
clr c
mov a,_b
subb a,_a
jnc 00104$
; 8051test.c:21: c += b;
mov a,_b
add a,_c
mov _c,a
; 8051test.c:22: b++;
inc _b
sjmp 00101$
00104$:
ret
;------------------------------------------------------------
;Allocation info for local variables in function 'f3'
;------------------------------------------------------------
; 8051test.c:26: void f3(void)
; -----------------------------------------
; function f3
; -----------------------------------------
_f3:
; 8051test.c:28: for( c=0; a>b; b++ )
mov _c,#0x00
00103$:
clr c
mov a,_b
subb a,_a
jnc 00105$
; 8051test.c:30: c += b;
mov a,_b
add a,_c
mov _c,a
; 8051test.c:28: for( c=0; a>b; b++ )
inc _b
sjmp 00103$
00105$:
ret
аналогичноConst14 писал(а):я вообще проблемы не вижу и не могу понять, в чём Вы её видите
Дык я об этом и сказал: do..while всегда быстрее или такой же как и while(). В простых циклах, когда компилятору удаётся превратить while() в do {} while, то разницы не будет.на целых 2 байта хуже показал себя цикл while
да-да-да. А потом удивляемся кто же пишет всё гавённое тормозящее ПО.весь сыр-бор из-за жалкого jmp, которого иногда может и не быть
Код: Выделить всё
if ((mode == ALARM_ACTIVE) || (mode == ALARM_COMPL))
{
// do something
}
Код: Выделить всё
if ((mode == ALARM_ACTIVE) || (mode == ALARM_COMPL))
{
// do something
}
а я всегда сам придерживался правила и другим советовал: скобки лишними не бывают. тем более что в MISRA вообще запрещается надеяться на приоритеты операторов...Siarzhuk писал(а):Внутренние скобки - лишние
Ну и напрасно. Не стоит идти против своего удобства, всего-лишь по какому-то совету с форума. Тут дело лично каждого. А компилятору - пофиг.Пока_без_кота писал(а):А я уже поудалял
Машинный код для машины, исходный - для человека. Поддерживаю предыдущих ораторов в принципе - скобок много не бывает. Автор или другой человек может читать исходный код и забыть о приоритетах, при беглом осмотре это тоже будет притормаживать внимание; разработчики ныне знают более одного языка программирования, вместо кучи памяток о приоритетах можно просто взять и поставить скобки; программирование => математика и эстетичнее выглядит заключённое в скобке выражение - тешит внутреннего перфекциониста.Внутренние скобки - лишние, поскольку приоритет оператора == равен 7 а у оператора || равен 12.