Dat is de C/C++/Java/etc. implementatie. Ik schrijf heel duidelijk:
"Een for lus gebruik je om een een blok voor een aantal specifieke waarden te doorlopen." Dat geldt in alle programmeertalen die ik ken. Ook in Basic: je wil het blok doorlopen voor de waarden die i van X tot Y achtereenvolgens aanneemt. Dat de syntax iets anders is, maakt er niet een andere constructie van. Je kunt de "i = X" als initialisatie, "next I" als iteratie en "to Y" als eindconditie beschouwen.
Je moet nadenken wat je wilt gaan doen. Als je 0 of meerdere keren een lus door wilt, is de for niet geschikt, dat klopt ook, want daarvoor heb je een while.
Stel ik heb in C in een functie die een array met strings print. Dan schrijf ik die toch echt zo:
C:
1
2
3
4
5
6
| void print(const char *strings[], int aantal)
{
int n;
for(n = 0; n < aantal; ++n)
printf("%s\n", strings[n]);
} |
De for-lus drukt namelijk precies uit wat ik wil doen: voor elk van de indices van de array (0 <= n < aantal), wil ik het juiste element printen. Omdat aantal ook best eens gelijk aan 0 kan zijn, ga ik niet opeens een while lus gebruiken, want dan moet ik opeens m'n initialisatie en iteratie buiten de lus gaan zetten! Daar wordt het absoluut niet beter op.
Wanneer je minstens 1 keer de lus door wilt, is de while dom, want je wilt bij 1 of meerdere keren de lus door aan het eind van de lus testen en niet vooraf, wat inhoudt dat je een do ... while of for gebruikt en niet een while.
De conditie in een for-lus wordt in C-achtige talen ook de eerste keer gecontroleerd hoor. De volgende twee constructies zijn semantisch equivalent:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
| // for-constructie
for(INITIALISATIE; ITERATIE; !EINDCONDITIE)
{
// OPERATIE
}
// while-constructie
INITIALISATIE;
while(!EINDCONDITIE)
{
// OPERATIE
// ITERATIE
} |
Het verschil zicht puur in de zelfbeschrijvende kwaliteit van de code. Gebruik van een for-statement drukt net iets anders uit dan een while-statement, maar het is niet gezegd dat je per se de een of de ander moet gebruiken.
Dit is ook de reden dat talen BEIDE aanbieden. Dat C-achtigen toevallig een compact for statement hebben waar je veel dingen in kwijt kunt is mooi, maar doet niet ter zake.
Wat heeft dat 'compact' zijn er dan mee te maken? En waarom doet het for-statement in C niet ter zake als we het over het for-statement in het algemeen hebben? Geldt het for-statement in C of C++ wel? Of alleen het for-statement in BASIC? En in shell scripts dan? Feit is dat je for-statement in C-achtige talen veel veelzijdiger is dan in andere talen (die zich vaak beperken tot een voorgeprogrammeerde initialisatie, iteratie en eindconditie);
Edit: m.a.w. met een while(expressie) { statements } constructie en een do {statements } while (expressie) heb je geen for statement nodig, en is dus overbodig. Dat deze wel in C zit is me dan ook een raadsel.
Dat ben ik dus met je eens. Hij zit er toch in, zoals al ik zei, omdat het gebruik van een for-statement een bepaald patroon is, dat door andere programmeurs eenvoudig begrepen wordt. Door het op de juiste manier te gebruiken, beschrijft de code zijn eigen werking beter. Volgens jouw redenatie is een do-while-constructie ook overbodig, omdat je die ook wel met een 'normale' while-constructie (en wat dubbele code) kan construeren. Eigenlijk heb je helemaal geen while-statement nodig als je labels en goto ondersteund (zoals in C het geval is).
Wie schrijft die 'goede' stijl voor? Jij?
Ja, ik.

Ik ben in de vele jaren dat ik pruts aan code al erg veel verhalen tegengekomen omtrent stijlen en wat goed/slecht is, dat ik mn neus echt ophaal voor dat soort opmerkingen, nofi

. In de jaren 80/begin 90 mocht je eigenlijk geen whiles gebruiken in je C code tenzij je niet anders kon, want while was een Wirth statement en hoorde eigenlijk niet in C thuis. "Een echte goede C programmeur programmeert op zn C's in C, niet op zn Pascal's". De allergrootste doodzonde was do {... } while (expression) gebruiken in C. Ik heb die dan ook behalve in 1 project op de uni dat resulteerde in een reprimande van mn docent nooit meer gebruikt.
Tja, lullig voor je dat je nu met zo'n trauma opgescheept zit (

grapje, ey) maar dat neemt niet weg dat het nuttig is als verschillende programmeurs eenzelfde stijl aanhouden. Dat maakt het simpelweg eenvoudiger om elkaar's code te lezen (en ook je eigen code terug te lezen). Ook blijkt in de praktijk gewoon dat bepaalde oplossingen beter geschikt zijn in bepaalde situaties dan anderen. Je kunt daar "je neus voor ophalen" maar daar verdwijnen die voordelen niet mee.
In 'C' was het iig zo dat bv de iterator variabele na de for loop 'undefined' was, qua waarde (oude Sun CC compilers iig) . In andere talen is dat niet zo, (geloof nu in C ook niet meer zo) en kun je die variabele die VOOR de for is geinitialiseerd weer gebruiken, waarom niet? Variabelen zijn een scope specific static set locaties waar je waarden neerzet die je in een zekere program state gebruikt en manipuleert. Als op een zekere tijd T variabelen door een loop worden veranderd (for statement), wat is er dan mis mee dat je die nieuwe toestand van die variabele na dat statement gebruikt? Ik zie dat niet.
In de oorspronkelijke versie van C mocht je helemaal geen lokale variabelen in een for-statement declareren. In C99 mag dat weer wel en daar zijn verder ook geen problemen mee, voor zover ik weet. Wel speelt een soortgelijk probleem een rol in C++: in ieder geval de C++ compiler van Microsoft plaatste de for-variabelen (onterecht) in de outer scope.
De reden dat ik dit zelf onwenselijk vind, is dat dit soort dingen onmogelijk zijn:
C++:
1
2
3
4
5
| for(int n = 0; n < 123; ++ n)
whatever(n);
for(int n = 0; n < 123; ++ n) // error: n is al gedeclareerd
whatever(n); |
Als de identifier slechts in de scope van het for-statement bestaat, is deze code wel goed. Als je toch graag die n buiten de lus wilt gebruiken, kun je 'm expliciet buiten de lus declareren. Dat is ook veel duidelijker.
C++:
1
2
3
4
5
6
7
| int n;
for(n = 0; n < 123; ++ n) // ok
whatever(n);
for(n = 0; n < 123; ++ n) // ok
whatever(n); |