Skämt och sido(unga förstår nog skämtet). Jag har skrivit en liten kod där jag ska skriva ut två tal varje sekund ungefär(beror på delay). Ena talet ska uppdateras varje gång den upprepas(1+) och andra talet ska uppdateras (1+) när första talet har uppdaterats 59 gånger.
struct return_values
{
int x;
int y;
};
void setup()
{
Serial.begin(9600);
}
void loop()
{
struct return_values t; // Deklarera t
time_clock(t.x , t.y); //Ur t kan man hämta det som är givet i en struct, t.ex t.x och t.y och använda som argument.
Serial.println(t.x); // Kontakta t IGEN och sök upp variabeln x och skriv ut den
Serial.println(t.y); // samma sak här
}
void time_clock(int time, int i) // argumentet t.x får variabeln time, int time.
{
if (i >= 59)
{
time = time++;
i = 0;
}
else
{
i = i++;
}
delay(1000);
struct return_values r; // deklarera r
r.x = time; // skicka ny data till r.x, vilket går till int x i structen.
r.y = i; // samma sak här
}
Men jag får bara detta
0
0
0
0
0
0
0
0
Jag vet vad som är fel, men jag vet inte hur jag ska lösa det.
När jag ser denna typ av kod.
När du deklarerar r i slutet av time_clock så blir det en helt ny struct som inte har något att göra med t som ligger i mainloopen. Den är dessutom bara giltig inne i den funktionen, och försvinner när funktionen avslutas.
Det finns flera sätt att lösa det på, t.ex. med pekare som Willow säger. Ett annat förslag är att deklarera t som en global struct, och använda den i både loop och time_clock.
Några tips:
i = i++ ser inte bra ut. Det fungerar ändå men är inte helt självklart. Skriv endast i++.
Vill du få lite precision så är det bättre att använda ett timerinterrupt för att räkna upp klockan. Då får du processortid över till annat också.
Du deklarerar ju en ny struct (r) i funktionen time_clock() och skriver dina värden i den. Varför gör du det om du vill att värdena skall hamna i den globala struct du redan deklarerat (t)?
Willow skrev:Vad tror du om att skicka in pekare som argument till time_clock() eller låta den returnera din struct?
Jag har inte börjat med pekare än och vet inte direkt vad det gör. Så jag får låta det vänta.
Kaggen skrev:Du deklarerar ju en ny struct (r) i funktionen time_clock() och skriver dina värden i den. Varför gör du det om du vill att värdena skall hamna i den globala struct du redan deklarerat (t)?
t.x = time; // skicka ny data till r.x, vilket går till int x i structen.
t.y = i; // samma sak här
och skippa deklarera (r) öht.
Alternativt snyggare/riktigare att göra som EBD föreslog, skicka pekare istället.
Jaha! Så en struct håller inte i några värden, utan en struct håller i dekelerationer av variabler så man slipper deklarera om dessa igen och igen och igen?
Jag gjorde det nu och det fungerar! Då vet jag vad struct gör! Trodde dem sparade data så man kunde kliva ut ur funktionen, och sedan hämta dessa igen om man känner för det. Då kanske det är klasser jag tänker på då?
Den sista koden ser lite farlig ut. Problemet är att variabler i en funcktion är lokala och läggs på stacken för denna funktion. Detta markeras som lediga när funktionen lämnas.
Risken finns att något annat använder samma minnesarea efter return eftersom detta minne är fritt igen. Fungerar ibland om man har tur, än värre blir det om man har interrupt.
struct return_values
{
int x;
int y;
};
void setup()
{
Serial.begin(9600);
}
void loop()
{
struct return_values t;
t.x = 0;
t.y = 0;
while(1)
{
t = time_clock(t.x , t.y);
Serial.println(t.x);
Serial.println(t.y);
}
}
struct return_values time_clock(int time, int i)
{
if (i >= 59)
{
time = time++;
i = 0;
}
else
{
i = i++;
}
delay(100);
struct return_values t = {time, i}; #Denna variabel kommer bara vara giltig inne i funktionen.
return t;
}