Dyskusja:C/Instrukcje sterujące: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
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:
<sourcesyntaxhighlight lang="C">
#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>
</source>
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):
<sourcesyntaxhighlight lang="c">
int PreIncrement(int a)
{
Linia 99:
return temp;
}
</syntaxhighlight>
</source>
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:
<sourcesyntaxhighlight lang="C">
int a = 0;
int i = 0;
for (;i<100;) {a=2*(i++);}
</syntaxhighlight>
</source>
Imho mogłaby wyglądać tak:
<sourcesyntaxhighlight lang="asm">
/* r9 - "a", r10 - "i" */
movq $0, %r9
Linia 117:
cmpq $99,%r10
jle $loop
</syntaxhighlight>
</source>
Jak wyglądałaby pętla:
<sourcesyntaxhighlight lang="C">
int a = 0;
int i = 0;
for (;i<100;) {a=2*(++i);}
</syntaxhighlight>
</source>
?
Moim zdaniem tak:
<sourcesyntaxhighlight lang="asm">
/* r9 - "a", r10 - "i" */
movq $0, %r9
Linia 136:
cmpq $99,%r10
jle $loop
</syntaxhighlight>
</source>
(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 :
<sourcesyntaxhighlight lang="C">
for (wyrażenie1; wyrażenie2; wyrażenie3) {
/* instrukcje do wykonania w pętli */
}
/* dalsze instrukcje */
</syntaxhighlight>
</source>
 
 
Jest równoważna (jeżeli wewnątrz pętli nie ma żadnych instrukcji '''continue''' z pętlą while :
<sourcesyntaxhighlight lang="C">
{
wyrażenie1;
Linia 176:
}
/* dalsze instrukcje */
</syntaxhighlight>
</source>
 
 
Czy nie powinno być :
 
<sourcesyntaxhighlight lang="C">
{
wyrażenie1;
Linia 191:
}
/* dalsze instrukcje */
</syntaxhighlight>
</source>
 
?
Powrót do strony „C/Instrukcje sterujące”.