Arduino - C nyelv és az IF szerkezet (volt LCD-óra)

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Arduino - C nyelv és az IF szerkezet (volt LCD-óra)

Hozzászólás Szerző: kapu48 »

Szerk. Admin.
Az előzménye a kérdéseknek a
http://avr.tavir.hu/modules.php?name=Fo ... ic&p=21516
oldalon található (LCD, óra és a szökőévek. Arduino alapon indult, C nyelv lett)

----------------------------------------------------------------------------------

Sajnos 1 mukkot sem értek a fenti sorokból!
Kéretik kommentezni!
A kezdők kedvéért!
:evil: :roll: :?: :x
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Hozzászólás Szerző: macsek »

csttom írta:macsek , a hónapok napjainak számítása ( a tömör változat) több helyen nem jó.

Ezt írtad:

Kód: Egész kijelölése

honaphossz = (ho==2) ? (! (ev%4) && (ev%400) ? 29 : 28) : (ho+(ho>7)%2) ? 31 : 30 ;
Helyesen pedig ez:

Kód: Egész kijelölése

honaphossz = (ho==2) ? ((!(ev%4) && (ev%100))||!(ev%400) ? 29 : 28) : ((ho+(ho>7))%2) ? 31 : 30;
hibák:
400 osztható év szökőév
100 osztható nem szökőév
november 30 napos

Egyébként nagyon jó.

Csttom
Köszönöm az észrevételt.
Sajnos még több helyen nem jó: az a zárójel hiány, amit kijavítottál azt eredményezte, h február kivételével minden hónap 31 naposra értékelődött ki. Ami enyhe túlzás

A szökőévekkel kapcsolatban is igazad van, az általad javított sor már tökéletes.

Itt egy tesztprogi, amit azért ütöttem össze, h látszódjon melyik függvény mit ad értékül és hol különböznek.
void setup()
{
  Serial.begin(9600);
}

void evteszt(int ev, byte startho, byte lepes)
{
  byte ho;
  byte honaphossz, h_csttom;
  
  for(ho=startho;ho<13;ho+=lepes)
  {
    // HIBAS!!!
    honaphossz = (ho==2) ? (! (ev%4) && (ev%400)             ? 29 : 28) :  (ho+(ho>7)%2) ? 31 : 30 ;
    // JO:, csttom altal javitva
    h_csttom =   (ho==2) ? ((!(ev%4) && (ev%100))||!(ev%400) ? 29 : 28) : ((ho+(ho>7))%2) ? 31 : 30;
          
    Serial.print(ev);
    Serial.print(".");
    Serial.print(ho);
    Serial.print(" m: ");
    Serial.print(honaphossz);
    Serial.print(" napos");
    if(honaphossz != h_csttom)
    {
      Serial.print(", csttom: ");
      Serial.print(h_csttom);
      Serial.print(" napos");
    }
    Serial.println("");
  }
}


void loop()
{
  int ev;
  
  evteszt(2011, 1, 1); 
  evteszt(2012, 1, 1); 
  
  for(ev=1978;ev<2014;ev++)
    evteszt(ev, 2, 5);

  for(ev=-100;ev<2414;ev+=100)
    evteszt(ev, 2, 12);

  while(1); // vegtelen ciklus
}
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Hozzászólás Szerző: macsek »

kapu48 írta:Sajnos 1 mukkot sem értek a fenti sorokból!
Kéretik kommentezni!
A kezdők kedvéért!
:evil: :roll: :?: :x
Ez egy tömör írásmódja az if-nek.
általános formája:

x = feltétel ? érték1 : érték2;

Azt jelenti, mintha ezt írtad volna:

Kód: Egész kijelölése

if(feltétel)
{
  x = érték1;
}
else
{
  x = érték2;
}
tehát ha a feltétel igaz, akkor a kérdőjel után írt érték1 -et, ha pedig hamis, akkor a kettőspont után írt érték2 -t fogja megkapni x.

Bár ezt már egyszer leírtam ;) (A ROSSZ kifejezésre, de ez szintaktikailag mindegy)

macsek 2012. Augusztus 6. Hétfő, 1:00-kor írta:
Robert írta:Akkor a kezdők kér(d)ését tolmácsolom:

Kód: Egész kijelölése

honaphossz = (ho==2) ? (! (ev%4) && (ev%400) ? 29 : 28) : (ho+(ho>7)%2) ? 31 : 30 ;
Hogyan bontható ki _értelmesen_ több if-re szerkesztve?
Robert írta: És jellemzően 0-ról kezdők vannak benne! akik annyit tanultak, amennyi eddig a tanfolyamon volt! NEM lehet háttértudásra építeni >300 főnél!
Bocsi, igazad van, van benne olyan szerkezet, amiről még nem volt szó.

honaphossz = (ho==2) ? (! (ev%4) && (ev%400) ? 29 : 28 ) : (ho+(ho>7)%2) ? 31 : 30 ;

Kód: Egész kijelölése

if(ho==2) // februar 28 v szokoevben 29 napos
{
   // szokoev van?
   
   // Szökoévek a következok: minden néggyel osztható év, kivéve a százzal is oszthatókat. 
   // Szökoévek viszont a 400-zal osztható évek. Vagyis a századfordulók évei közül 
   // csak azok szökoévek, amelyek 400-zal is oszthatók.
   // http://hu.wikipedia.org/wiki/Sz%C3%B6k%C5%91%C3%A9v

   honaphossz = 28;
   
   if( (ev%4)==0 ) // neggyel oszthato ev
   {  
	  if( (ev%100)!=0 ) // nem oszthato 100-zal akkor egyertelmuen szokoev
		 honaphossz = 29;
	  else
	  {
		 if( (ev%400)==0 )	// ha 400-zal oszthato akkor szokoev
			honaphossz=29;
	  } 

   } // neggyel oszthato?
	  
}
else // nem februar
{
   if(ho>7) // julius utan valtas van.
   {
	  if(ho%2 == 1) // ha paratlan, azaz kettovel osztva a maradek 1
	  { // szept, nov
		 honaphossz = 30; 
	  }
	  else // aug, okt, dec
		 honaphossz = 31;		 
   }
   else // jan-juli
   {
	  if(ho%2 == 1) // ha paratlan, azaz kettovel osztva a maradek 1
	  { // jan, marc, maj, jul
		 honaphossz = 31; 
	  }
	  else // (februart kiszurtuk), apr, jun
		 honaphossz = 30;		 
	  
   }
}

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Sajnos még mindig keveset tudok ahhoz, hogy megértsem, de megpróbálom.

„honaphossz =” a végén ebben kapjuk az eredményt.
„(ho==2)” az első feltétel „?” if
„(! (ev%4) && (ev%400) ? 29 : 28 )” Igaz ág = 31
: „(ho+(ho>7)%2) ?” Hamis ág = 30

Eddig jó?

Most a belső függvények:
„(ev%400)” feltétel „?” if Igaz ág = 29, : Hamis ág = 28

???

Á feladom! Maradok a hagyományos módszernél.
Azt is bőven ellátva magyarázatokkal, hogy pár év múlva is könnyen visszafejtsem.

:oops:
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Hozzászólás Szerző: macsek »

kapu48 írta:Sajnos még mindig keveset tudok ahhoz, hogy megértsem, de megpróbálom.
Erről szól minden tanulás :)
Egyébként pedig gratulálok, egészen közel jársz a megfejtéshez
kapu48 írta: „honaphossz =” a végén ebben kapjuk az eredményt.
IGEN


macsek írta:
csttom írta:macsek , a hónapok napjainak számítása ( a tömör változat) több helyen nem jó.

Ezt írtad:

Kód: Egész kijelölése

honaphossz = (ho==2) ? (! (ev%4) && (ev%400) ? 29 : 28) : (ho+(ho>7)%2) ? 31 : 30 ;
Helyesen pedig ez:

Kód: Egész kijelölése

honaphossz = (ho==2) ? ((!(ev%4) && (ev%100))||!(ev%400) ? 29 : 28) : ((ho+(ho>7))%2) ? 31 : 30;
Elemezzük inkább a csttom által javított sort, mert felépítését tekintve azonos, ugyanakkor az ad jó eredményt.

kapu48 írta: „(ho==2)” az első feltétel „?” if
IGEN
kapu48 írta: „(! (ev%4) && (ev%400) ? 29 : 28 )” Igaz ág = 31
IGEN
kapu48 írta: : „(ho+(ho>7)%2) ?” Hamis ág = 30

Eddig jó?
IGEN, tökéletes!

kapu48 írta: Most a belső függvények:
„(ev%400)” feltétel „?” if Igaz ág = 29, : Hamis ág = 28
az igaz és a hamis ág jó, a feltétel nem az, hanem:

Kód: Egész kijelölése

! (ev%4) && (ev%400)
illetve a jó kóddal:

Kód: Egész kijelölése

( !(ev%4) && (ev%100) ) || !(ev%400)
kapu48 írta: Á feladom! Maradok a hagyományos módszernél.
Azt is bőven ellátva magyarázatokkal, hogy pár év múlva is könnyen visszafejtsem.

:oops:
Egyrészt nyugodtan maradj a "hagyományos módszer"-nél, a fordító feltehetőleg kb. ugyanazt a kódot fogja fordítani belőlük. Ha ennek az átláthatóságával baj van az mehet a program minőségének a rovására, lásd én is elszúrtam a zárójel kifelejtésével. Pedig hidd el, értem. ;-)

Ez olyan helyekre való, ahol tömören akarod leírni a kódot. És igazából ennél egyszerűbb kifejezésekhez szokták használni.
Viszont mostmár ezt is megtanultad és érteni fogod, ha vhol ilyet látsz. Sőt, az is lehet, h egy-két helyre te is írsz majd átlátható ilyet.
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Hozzászólás Szerző: macsek »

Bocsi, újra átolvastam és van némi javítani való benne:

Kód: Egész kijelölése

honaphossz = (ho==2) ? ( (!(ev%4) && (ev%100)) || !(ev%400) ? 29 : 28) : ((ho+(ho>7))%2) ? 31 : 30;

A kifejezés majd a hónaphossz változónak ad értéket.
honaphossz = (ho==2) ? ( (!(ev%4) && (ev%100)) || !(ev%400) ? 29 : 28) : ((ho+(ho>7))%2) ? 31 : 30;
Átírva if-ekre:
if( (ho==2) )
{
honaphossz = ( (!(ev%4) && (ev%100)) || !(ev%400) ? 29 : 28);
}
else
{
honaphossz = ((ho+(ho>7))%2) ? 31 : 30;
}
Tovább boncolva az igaz ág:

honaphossz = ((!(ev%4) && (ev%100)) || !(ev%400) ? 29 : 28);
Ami if-ül:
if(( !(ev%4) && (ev%100)) || !(ev%400))
{
honaphossz = 29;
}
else
{
honaphossz = 28;
}
A hamis ágat pedig nem boncolom tovább, azt tedd meg te gyakorlásképpen.
Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

Hozzászólás Szerző: SzLacus »

Hú eddig el fogunk jutni? Mármint, hogy ilyen "hieroglifákkal" írjunk le valamit? Vagy ezt az arduino meg sem eszi, csak a kibontott írásmódot. Tudom, próbáljam ki. :-)
De hogy én is kérdezzek valamit. A hónapok neveinek megadásánál miért betűnként építed fel, miért nem 'Jan';' Feb'; stb. Biztos van valami oka, vagy előnye ennek, amire én nem gondolok.
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Hozzászólás Szerző: macsek »

SzLacus írta:Hú eddig el fogunk jutni? Mármint, hogy ilyen "hieroglifákkal" írjunk le valamit?
Hát látod, Kapu48 már eljutott és szerintem te is :)
SzLacus írta: Vagy ezt az arduino meg sem eszi, csak a kibontott írásmódot.
megeszi
SzLacus írta: A hónapok neveinek megadásánál miért betűnként építed fel, miért nem 'Jan';' Feb'; stb. Biztos van valami oka, vagy előnye ennek, amire én nem gondolok.
Ez megint kicsit túlmutat azon a szinten, ahová eddig eljutottunk, de sebaj, jó, h észrevetted.
Ha azt írod le, hogy "Jan", ami egy karakterlánc (string) akkor az 4 byte lesz, mert a karakterláncok végére egy lezáró jelet tesz a fordító, hogy kiírásnál, másolásnál stb. észrevegye ha a végére ér. (Ez a lezáró jel a 0 kódú karakter.)
Ugyanígy a "J" KÉT karaktert foglal. Ez is char tömb lesz.

Ha 'J' formát használjuk (szimpla aposztróf, avagy talán magyarosabban felső vessző) akkor az char típusú egyedi elem lesz, nem tömmb.

Remélem nem kutyultalak meg vele.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Az összevont if és társai nem az Arduino sajátja. Az a mögöttes C fordítóé. Igaz, hogy megeszi, de ez inkább C tanfolyam már, mint Arduino. Szóval ez a hieroglif írás nem igazán lesz (eddig nem terveztem :) ).


Jan/Feb és egyéb sztring-kezelések a tervek közt szerepelnek. Pont az óraprojekt kapcsán.
A beállítandó időt hogyan is adod meg? Beolvasol egy karakterláncot (szövegsort). Pl. most a pontos idő:
15:35:04<enter>
És ezt hámozd ki. De mi van, ha valaki így adja meg:
15:35:4<enter>
Sőt, mi van ha a dátumot is kezeled? Milyen nyelven? Milyen elválasztó-karakterrel? Milyen év-hó-nap sorrenddel?
És ha intelligens az órád, akkor nem azt írja ki, hogy 2. hó, hanem Február. De mi van ha a hétköznapok is kellenek, és teljes EUban teríted az univerzális órát? A hétköznapok német/angol/magyar nyelven minimum kellenek....
De ezek a kérdések még később merülnek fel.

Szóval igen, kell a tömbök kezelése és a szöveges "boncolások" is :P ...
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

A válasz, szüli a következő kérdést!

Most ezzel nyerünk valamit?
Mert ha?
Ezek a karakterek elkerülnek valahova a memóriába és mindre lesz 1db. 2Bytes mutató?

:?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

A programozó lusta népség. 1/4 annyit gépel így :)
Bascomban Te kiírod azt, hogy print? Törődsz a változók kis/nagybetűjével?

Nálam a print egy ? és egy szóköz. A változók autoformázottak:).
Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

Hozzászólás Szerző: SzLacus »

Teljesen igaz. A lustaság a fejlődés motorja. De azért céltalanul nem vagyunk lusták. Továbbra is a hónap neveinek megjelenítésére koncentrálva, létrehozunk egy 12*3 elemű tömböt a 12 hónapunk nevével. De ezt 12 elemben is megtehetnénk, ha az egyes hónapokat jelentő három betűt egybe írnánk. A null lezárást elkerülendő csak így 'Jan'.....'Dec'. A kiírásnál úgyan úgy a honapok tömb ho elemét választanánk a számolás alapján, csak nem kéne az 1...2...3 elemét külön egymás után kizavarni a kijelzőre. Vagy tévedek? Annak volna valami olyan következménye ami most nem látszik, de majd jól beleütközünk, és itt még nem kerül magyarázatra?
Másik kérdésem a tömör írásmóddal kapcsolatban adódik.
honaphossz = (ho==2) ? ( (!(ev%4) && (ev%100)) || !(ev%400) ? 29 : 28 ) : ((ho+(ho>7))%2) ? 31 : 30;
Tudjuk minek kell kijönni, így könnyebb, de egy 4-el osztás maradékának negálásával kezdünk egy & kapcsolatot. A maradék lehet 0-3-ig. Ebből nekünk a 0 a nyerő és annak negálása 1-et eredményez az & egyik bemenetén, tehát ekkor már csak a másik bemenettől függ a dolog. De az 1-3 maradékok esetén mi lesz a negálás eredménye?
Utána az & másik bemenete a 100-as osztás maradéka. Ugyan ez a kérdésem, csak itt nincs negálás. Ami nem nulla az 1-nek számít, egy logikai műveletben? Mert itt a nulla maradék esetén lehet nem szökőév.
A 400-as osztásnak meg bele sem fér egy bájtba a maradéka. Azzal mi a helyzet? Értem én, hogy most pont a nulla maradék az ami nekünk kell, és negálva a vagy kapcsolat eredménye az, hogy a 400-al osztható év az szökőév, csak mi történik belül.
(Vicces, hogy az idézetben smile lett a 8-as és zárójelből, de az érthetőséget talán nem zavarja.)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

? if < feltétel vizsgálat nem tárolja az eredményt!
A lényeg, ha 0 akkor hamis ág, ha nem nulla akkor igaz ágra adja a vezérlést.
Ott pedig csak egyszerű értékadás szerepelhet.
Avatar
GPeti
Bitmanipulátor
Hozzászólások: 131
Csatlakozott: 2011. március 3. csütörtök, 7:00

Hozzászólás Szerző: GPeti »

Az Arduino Help-jében (arduino-1.0.1/reference/index.htm) nem találom a ? és a : jelentését.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Mert ez a jelölés C és nem Arduino. Csak az ifjak kihagytás a beszélgetés elejéből .... :evil:

U.i.: a Tanfolyam címe emlékeztetőül: 60 nap alatt Arduino.
Válasz küldése