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.

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 :-)

nee, tot en met 0, en dan stoppen.

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 ?

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.


for(cnt = 2; cnt >= 0; cnt --){
    // doe wat
}

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.

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

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);

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.

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.

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;

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.