Dyskusja:C/Instrukcje sterujące: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
→pętla for jako while: nowa sekcja |
Nie podano opisu zmian |
||
Linia 53:
Nie jestem przekonany co do wyższości preinkrementacji nad postinkrementacją. Pozwoliłem sobie przeprowadzić mały test, który wprowadził mnie w osłupienie. Oto kod programu testowego:
<
#define N 100000000
#include <time.h>
Linia 72:
printf ("1) %fs\n2) %fs\n",t1/(CLOCKS_PER_SEC*1.0f),t2/(CLOCKS_PER_SEC*1.0f));
}
</syntaxhighlight>
Wyniki na moim komputerze są następujące:
Linia 86:
Lub zamieniały się miejscami (granica błędu). Innymi słowy - nie była widoczna szczególna różnica, uzasadniająca wybór którejkolwiek z rodzajów inkrementacji.
Spotkałem się z [http://www.codeguru.com/forum/archive/index.php/t-384898.html opinią], która uzasadnia wydłużenie działania "i++" względem "++i" w następujący sposób (cytat):
<
int PreIncrement(int a)
{
Linia 99:
return temp;
}
</syntaxhighlight>
Oczywiście ma to sens w przypadku, gdy implementujemy takie operatory w języku C. Nie zapominajmy jednak, że na poziomie asemblera, do którego pośrednio tłumaczony jest C oraz na poziomie kodu maszynowego granica między "i++" a "++i" nieco się zaciera. Spróbujmy się zastanowić, jak mogłaby wyglądać pętla wyrażona w C:
<
int a = 0;
int i = 0;
for (;i<100;) {a=2*(i++);}
</syntaxhighlight>
Imho mogłaby wyglądać tak:
<
/* r9 - "a", r10 - "i" */
movq $0, %r9
Linia 117:
cmpq $99,%r10
jle $loop
</syntaxhighlight>
Jak wyglądałaby pętla:
<
int a = 0;
int i = 0;
for (;i<100;) {a=2*(++i);}
</syntaxhighlight>
?
Moim zdaniem tak:
<
/* r9 - "a", r10 - "i" */
movq $0, %r9
Linia 136:
cmpq $99,%r10
jle $loop
</syntaxhighlight>
(Kod nie był testowany - jest on raczej pewnego rodzaju demonstracją praktycznej różnicy w budowie pętli na poziomie kodu asemblera. Fakt przechowywania zmiennych w rejestrach także nie powinien być brany pod uwagę - analogiczna sytuacja miałaby miejsce w przypadku operacji na pamięci.)
Różnica polega tylko i wyłącznie na kolejności instrukcji. Nigdzie tutaj nie musimy tworzyć dodatkowej zmiennej, a szybkość "i++" oraz "++i" moim zdaniem zależeć będzie tylko i wyłącznie od kompilatora i jakości generowanego przez niego kodu. Ośmielę się postawić tezę, że przy współczesnych kompilatorach nie ma to znaczenia.
Linia 158:
Pętla for :
<
for (wyrażenie1; wyrażenie2; wyrażenie3) {
/* instrukcje do wykonania w pętli */
}
/* dalsze instrukcje */
</syntaxhighlight>
Jest równoważna (jeżeli wewnątrz pętli nie ma żadnych instrukcji '''continue''' z pętlą while :
<
{
wyrażenie1;
Linia 176:
}
/* dalsze instrukcje */
</syntaxhighlight>
Czy nie powinno być :
<
{
wyrażenie1;
Linia 191:
}
/* dalsze instrukcje */
</syntaxhighlight>
?
|