for lus: aftellen

trix

Golden Member

simpele vraag denk ik:

ik heb een for lus:


for (row_byte = 0; row_byte < 3; row_byte ++) 

die doorloopt: 0, 1, en 2

maar nu wil ik aftellen, dus: 2, 1, en 0


for (row_byte = 2; XXX; row_byte --) 

wat moet er dan op de plek van XXX ?

mijn dank is groot.

eigenwijs = ook wijs

Daar moet staan de voorwaarde waarin je de loop wilt laten lopen. Ik schat in dat je tot aan 0 wilt gaan, dus... Maar het kan ook zijn dat je wilt doortellen tot -10. Dan wordt het anders :-)

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
trix

Golden Member

nee, tot en met 0, en dan stoppen.

eigenwijs = ook wijs
trix

Golden Member

ik doe het nu even zo:


for (row_byte_temp = 3; row_byte_temp > 0; row_byte_temp --) 
{
	row_byte = row_byte_temp - 1;

maar of dat de juiste methode is ?

eigenwijs = ook wijs
EricP

mét CE

Heb je nooit assembly geschreven? 'for' loops bestaan niet... Het is de compiler die er wat van bakt. Verder kun je elke for loop als een while loop schrijven (dat zal de compiler ook wel doen). Wellicht wordt het dan inzichtelijker.

Let nog wel even op het verschil tussen 'while' en 'do... while'.

row_byte_temp=3;
while (row_byte_temp>=0)
{
  //Do something

  row_byte_temp--;
}

Het is in code wellicht een heel klein beetje langer. Maar in wat de controller doet niet. Zo'n voorbeeld maakt ook gelijk inzichtelijk dat wanneer je binnen je loop iets met je row_byte_temp doet, dat gewoon kan. Net als bij een 'for' loop, alleen daar is het 'vies' of 'not done' ofzo. In code maakt het niks uit.

En voor iemand zegt 'een while loop bestaat ook niet'... Redelijk correct. Maar die kun je wel 1-op-1 naar assembly vertalen.

buckfast_beekeeper

Golden Member


for(cnt = 2; cnt >= 0; cnt --){
    // doe wat
}
Van Lambiek wordt goede geuze gemaakt.

Je zegt 'm voor :-) Ik hoopte met mijn antwoord een goede hint gegeven te hebben. Werkte niet.

PS, die voorwaarde cnt>=0 werkt alleen als cnt een signed variabele is, anders is ie altijd >=0, ook als je decrement vanaf 0.

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
trix

Golden Member

tuurlijk, >= 0;
had ik eigenlijk zelf ook wel kunnen bedenken |:(
tnx

eigenwijs = ook wijs

Met -Wall krijg je van gcc tegenwoordig gelukkig een foutmelding als je dat perongeluk doet.

Zo'n index die heeft normaliter een range van 0 ... X, dus een "unsigned" lijkt dan prima te passen. Als je dan later zo'n tel-naar-beneden lus nodig hebt, dan kan het een verrassing zijn dat >= 0 niet werkt. Dus fijn dat ie daarvoor waarschuwt.

Er zijn ook alternatieven.


for (i=4;i>0;) {
   i--;
   ...
}

i=3;
while (1) {
  ...
  i--;
  if(i == 0) break;
}

i=4;
do {
  i--;
  ...
  } while (i > 0);
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
buckfast_beekeeper

Golden Member

Op 21 mei 2020 10:15:05 schreef flipflop:
Je zegt 'm voor :-) Ik hoopte met mijn antwoord een goede hint gegeven te hebben. Werkte niet.

PS, die voorwaarde cnt>=0 werkt alleen als cnt een signed variabele is, anders is ie altijd >=0, ook als je decrement vanaf 0.

Maak je er toch

for(int cnt = 2; ....)

van. Heb je een range van -32767 tot 32767.

@flipflop hier onder: in java is dat de normale syntax. De cnt blijft zo beperkt tot de for lus. Kom je nooit in de knoei met een teller die elders gebruikt werd. Uiteraard kan je ook een byte gebruiken. Persoonlijk vind ik het net heel duidelijk.

Van Lambiek wordt goede geuze gemaakt.

oh wat lelijk, declaratie en statement door elkaar. Rommelig, onoverzichtelijk en dus foutgevoelig. Paar je bevestigt wat ik al schreef, da's dan wel mooi :-) Een int is wel aardig overkill hier natuurlijk voor een tellertje van 0..3.

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein

Oh, wat mooi. Declaratie en initialisatie precies op de plaats waar je hem nodig hebt. En na de for loop is hij weer verdwenen.

Blijkbaar verschillen de meningen :)

Formeel is een "int" hier het beste datatype. (in C, volgens de standaard).

De "int" is een formaat integer wat door de CPU handig gebruikt kan worden.

Bijvoorbeeld op een ARM is dat 32 bits. Als je een byte zou declaren en dan een ++ doet, dan moet de compiler gaan zorgen dat die waarde niet boven de 256 gaat komen en zo. Nu blijken er genoeg byte-instructies te zijn dat ik zonder optimalisatie bij dit stukje code met zowel byte als int 12 instructies in de loop tel:

int addit (int t)
{
  unsigned char  i;

  for (i=0;i<4;i++) 
     t+= i+t;
  return t;
}

Als ik hem wel laat optimaliseren, zegt de compiler: je kan de pot op met je test-code:

  return (t << 4) + 11;
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Op 21 mei 2020 14:50:53 schreef flipflop:
oh wat lelijk, declaratie en statement door elkaar. Rommelig, onoverzichtelijk en dus foutgevoelig.

Absoluut niet, eleganter en minder foutgevoelig omdat de variable alleen in de scope van je for loop zichtbaar is.

Een int is wel aardig overkill hier natuurlijk voor een tellertje van 0..3.

Ligt eraan, een int is voor de meeste processoren het meest efficiente type en minimaal 16-bits.

Alleen voor 8-bits cpu's is een 'int' een beetje overkill. Voor alle andere cpu's een een 'char' op deze plaats inefficienter.

-edit- Post een beetje gekruist met die van rew.

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.