Vad är det som skapar en "död punkt" i denna loop?

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
swp
Inlägg: 63
Blev medlem: 31 december 2010, 00:54:56

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av swp »

Det ser ut som om step är deklarerad som en unsigned char. Den kommer då alltid att vara större än eller lika med noll. Så det är nog det som gör att din loop som räknar ner inte stannar. Den borde inte vara unsigned utan int eller char.
Mr Andersson
Inlägg: 1407
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Mr Andersson »

Zkronk skrev:På den andra for-loopen, blir det inte konstigt när villkoret för att den ska fortsätta köras är "större eller lika med noll"? Den kommer ju köras även när step är noll och subtrahera ett så att step blir lika med -1, och när du försöker komma åt constants[-1] så blir det nog problem?
Nej det stämmer inte. step minskas efter varje iteration, inte före.
Sista iterationen kommer att vara step==0, sen blir step=-1 (*) och loopen avbryts.
Att sen step är -1 blir bara problem om du försöker använda constants[step] efter loopen.
Som swp sagt ovan är det för att step är unsigned.

*) Eller skulle ha blivit om den var signed iaf :)

Edit/Tillägg:
Och som ie nämnde så är value odefinierad första iterationen, och kommer inte heller använda sista värdet.
Byt plats på
PWM1_Set_Duty(value);
och
value = constants[step];

Dvs, hämta value från constants innan du använder value-variabeln.
Senast redigerad av Mr Andersson 21 november 2014, 22:13:21, redigerad totalt 1 gång.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Magnus_K »

Såg detta när jag körde debuggen men dumt att jag inte skrev något om det. När den "fortsatte förbi 0" så rullade den alltså runt och gick direkt till 255 för att sedan räkna ner igen. Det är väl för att den alltså är unsigned? Signed går mellan ±128.

Hmm, hur stor kan en int vara då? Hittar inget om det utan att det är hela nummer, positiva eller negativa. Väljer man inte signed/unsigned för att inte allokera så mycket minne eller har jag förstått det fel?
ie
EF Sponsor
Inlägg: 1371
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av ie »

I detta fall spelar ++step eller step++ ingen roll, då det utförs på ett specifikt ställe i programmet (i for-loopen).

Däremot spelar det roll om du t ex skriver value=constants[++step] eller value=constants[step++].

Alltså, ska du inkrementera före eller efter du använder värdet? I for-loopen finns inget före eller efter, om du förstår hur jag menar.
Mr Andersson
Inlägg: 1407
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Mr Andersson »

Magnus_K skrev:Såg detta när jag körde debuggen men dumt att jag inte skrev något om det. När den "fortsatte förbi 0" så rullade den alltså runt och gick direkt till 255 för att sedan räkna ner igen. Det är väl för att den alltså är unsigned? Signed går mellan ±128.

Hmm, hur stor kan en int vara då? Hittar inget om det utan att det är hela nummer, positiva eller negativa. Väljer man inte signed/unsigned för att inte allokera så mycket minne eller har jag förstått det fel?
Lite förenklat sagt så har unsigned char 8 bitars "värdesiffror", 0-255, och signed char har 7 bitars värdesiffror plus 1 bit för att indikera plus eller minus. -128 till +127

Hur stor int är beror på processorn, men "sizeof(int)*8" ger dig hur många bitar en unsigned int har. signed har en mindre och en "sign bit". 16 eller 32 bits int är nog vanligast skulle jag vilja påstå.

Om 'int' utan "qualifier"(*) betyder signed eller unsigned beror på kompilatorn, och ofta kan man själv välja vilket det ska vara.

*) Vet inte vad det kallas på svenska, men tex. signed eller unsigned.
Användarvisningsbild
Icecap
Inlägg: 26622
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Icecap »

I C är en 'int' den "enklaste storlek att hantera i minnet", dock minst 8 bit.

I en 8-bit µC brukar den vara 8 bit, i en 16 bit µC brukar den vara 16 bit osv.

int är ganska speciell eftersom man inte kan veta exakt hur många bytes den tar och därmed inte heller hur stora värden den kan jobba med.

Jobbar man i C99 eller nyare kan man säkerställa storleken av en variabel.
Mr Andersson
Inlägg: 1407
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Mr Andersson »

Magnus_K skrev:Väljer man inte signed/unsigned för att inte allokera så mycket minne eller har jag förstått det fel?
Glömde svara på den här biten.
signed och unsigned tar båda lika mycket plats. Det som avgör hur mycket minne som används är själva typen av variabel, tex. char, short, int, long, etc.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Magnus_K »

@Mr Andersson:
Din edit i förr-förra inlägg utförde jag efter ie:s påpekande. Ändringen syns i sista inlägget på sidan 1 (och nedan).
Tack för din förklaring om bit-storlek. Dock förstår jag fortfarande inte vad det spelar för roll för mina små loopar här? Jag vill ju hålla värdet mellan 0 och 99 så unsigned, signed eller int/char bör väl göra någon skillnad?

@ie:
Tror jag hänger med på vad du menar men börjar bli lite förvirrad nu. Ska jag flytta ner ++ och -- till step i loopen?

Postar hela koden en gång till så vi pratar om samma sak.

Kod: Markera allt

unsigned char step;
unsigned char value;
const unsigned char constants[100] = {1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,
                                      11,12,12,13,13,14,14,14,15,15,16,16,17,17,18,
                                      18,19,19,20,20,21,21,22,23,23,24,25,25,26,27,
                                      27,28,28,30,31,32,33,34,36,37,39,41,42,44,45,
                                      47,49,52,55,57,60,62,65,68,71,75,79,83,87,91,
                                      95,99,103,107,111,115,119,123,127,131,134,138,
                                      142,146,150,154,158,162,166};


void main() {

 step = 0;
 value = 1;

        while(1)
         {
                for(step = 0; step <= 99; ++step)
                {
                value = constants[step];
                PWM1_Set_Duty(value);
                Delay_ms(30);
                }
                for(step = 99; step >= 1; step--)
                {
                value = constants[step];
                PWM1_Set_Duty(value);
                Delay_ms(30);
                }
         }
}
Mr Andersson
Inlägg: 1407
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Mr Andersson »

> Din edit i förr-förra inlägg utförde jag efter ie:s påpekande. Ändringen syns i sista inlägget på sidan 1 (och nedan).
Lessen, missade det.

> Tack för din förklaring om bit-storlek. Dock förstår jag fortfarande inte vad det spelar för roll för mina små loopar här? Jag vill ju hålla värdet mellan 0 och 99 så unsigned, signed eller int/char bör väl göra någon skillnad?
Problemet är när man kombinerar unsigned och >=0. En unsigned char kan inte vara negativ och kommer alltid att vara större eller lika med 0. (0-1) slår runt och blir maxvärdet istället. För unsigned char 255.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Magnus_K »

Ahhaaa, så när jag skrev så här i andra for-loopen:

Kod: Markera allt

for(step = 99; step >= 0; step--)
så räckte det att när jag väl kom hit så gick den helt enkelt från 99 ner till 0, och sen slog om till 255 men lämnade aldrig den här for-loopen?
swp
Inlägg: 63
Blev medlem: 31 december 2010, 00:54:56

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av swp »

Precis behåll loopen så som du hade den från början men ta bort unsigned från deklarationen av step så borde det fungera:

Kod: Markera allt

char step;
for( step=99; step>=0; step-- )
...
Användarvisningsbild
Icecap
Inlägg: 26622
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Icecap »

255 är ju mer än 0 eller hur? Alltså lämnar den aldrig loopen.
Mr Andersson
Inlägg: 1407
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Mr Andersson »

> så räckte det att när jag väl kom hit så gick den helt enkelt från 99 ner till 0, och sen slog om till 255 men lämnade aldrig den här for-loopen?

Precis. Det som händer i din for-loop sker i den här ordningen:
1) Loopen körs ett varv.
2) step minskas med 1
3) step kontrolleras mot >=0 som i det här fallet alltid kommer att vara sant, dvs en oändlig loop :)
Användarvisningsbild
90kar08
Inlägg: 1602
Blev medlem: 3 september 2009, 15:27:45
Ort: Staffanstorp

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av 90kar08 »

Det du tänkte med att spara minne med att använda unsigned är delvis sant. En int tar lika stor plats i minnet oavsett om den är signed eller unsigned och det får plats lika många tal i båda. Men i en unsigned int får du plats med större tal (till priset att variabeln inte kan bli negativ). Detta kan göra att man ibland kan välja en mindre datatyp. 200 till exempel får inte plats i en signed char men går bra i en unsigned char vilket gör att man slipper ta till en int och på så vis kan man spara minne.

Icecap: En int är alltid minst 16 bitar.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Magnus_K »

Bra, bra. Nu är jag på spår igen.
Ska testa det du säger swp under kvällen och bara för att kolla så testade jag precis det du sa Mr Andersson, att använda "sizeof(int)*8".
Jag fick tillbaka värdet "16" så det får vi väl ta som 16 bitar i processor jag använder nu.

EDIT: Tack för förklaringen 90kar08 :tumupp: .
EDIT: Det blev samma resultat swp...
Skriv svar