 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
damo Član


Pridružen-a: Čet 31 Jul 2003 13:45 Prispevkov: 2008 Aktiv.: 8.48 Kraj: Krško
|
Objavljeno: Sob Avg 22, 2009 12:23 pm Naslov sporočila: problem s kazalci v C-ju |
|
|
imam problem s kazalci, funkcija (ki sem jo skopiral iz interneta) ne vrne pravega rezultata.
Koda: |
unsigned int MemRead(unsigned char SlaveAddress,unsigned char command)
{
unsigned int sdata; // Data storage (DataH:DataL)
unsigned char Pec; // PEC byte storage
unsigned char DataL; // Low data byte storage
unsigned char DataH; // High data byte storage
.
.
.
.
*((unsigned char *)(&sdata))=DataL; //
*((unsigned char *)(&sdata)+1)=DataH ; //data=DataH:DataL
return (sdata);
|
če namesto zadnjih treh vrstic napišem:
Koda: |
return (DataL+256*DataH);
|
pa vrne rezultat (sicer ne čisto pravi..... )
mi lahko kdo razloži, kje je napaka? tile pointerji me vedno malo zmedejo...[/code] |
|
Nazaj na vrh |
|
 |
Sokrat Član


Pridružen-a: Čet 25 Avg 2005 11:00 Prispevkov: 5584 Aktiv.: 23.57
|
Objavljeno: Sob Avg 22, 2009 12:40 pm Naslov sporočila: |
|
|
Zakaj pa sploh take komplikacije ?
Koda: |
sdata = (DataH << 8) | DataL;
return sdata;
|
_________________ Ka ti bo pa torba ce si kupu kolo ? |
|
Nazaj na vrh |
|
 |
damo Član


Pridružen-a: Čet 31 Jul 2003 13:45 Prispevkov: 2008 Aktiv.: 8.48 Kraj: Krško
|
Objavljeno: Sob Avg 22, 2009 12:42 pm Naslov sporočila: |
|
|
ja, tisto s kazalci je bilo original. jaz sem dal namesto tega :dataL+256*dataH
vidim pa da je tvoj predlog še bolj optimiziran  |
|
Nazaj na vrh |
|
 |
Sokrat Član


Pridružen-a: Čet 25 Avg 2005 11:00 Prispevkov: 5584 Aktiv.: 23.57
|
Objavljeno: Sob Avg 22, 2009 12:49 pm Naslov sporočila: |
|
|
Tisto originalno je ena huda zmeda in sem precej preprican ne pocne tega, kar ti zelis, vsaj sodec po tvoji izvedbi resitve.
&sdata je kazalec na sdata (torej naslov te spremenljivke) ... Napisi kaj zelis doseci. _________________ Ka ti bo pa torba ce si kupu kolo ? |
|
Nazaj na vrh |
|
 |
damo Član


Pridružen-a: Čet 31 Jul 2003 13:45 Prispevkov: 2008 Aktiv.: 8.48 Kraj: Krško
|
Objavljeno: Sob Avg 22, 2009 2:13 pm Naslov sporočila: |
|
|
saj moja rešitev, pa tudi tvoja, delujejo.
tista originalna pa je verjetno napisana tako, da še kak bajt kode prišpara...
v glavnem, cilj je, da zapakiram unsigned char dataH in dataL v spremenljivko int sdata, ki jo funkcija vrne. |
|
Nazaj na vrh |
|
 |
Sokrat Član


Pridružen-a: Čet 25 Avg 2005 11:00 Prispevkov: 5584 Aktiv.: 23.57
|
Objavljeno: Sob Avg 22, 2009 2:40 pm Naslov sporočila: |
|
|
Tista originalna ne dela tega.
Ce res rabis optimizacijo, naredis rocno v assemblerju, a za ta konkretni primer dvomim da je prevajalnik (bistveno) manj ucinkovit kot moja izvedba. _________________ Ka ti bo pa torba ce si kupu kolo ? |
|
Nazaj na vrh |
|
 |
chaos Član


Pridružen-a: Sob 16 Sep 2006 22:12 Prispevkov: 1063 Aktiv.: 4.66 Kraj: Zagorje ob Savi
|
Objavljeno: Sob Avg 22, 2009 2:59 pm Naslov sporočila: |
|
|
Originalna koda bi sicer morala najbolj optimalno (brez šiftanja / množenja in seštevanja / oranja) narediti to, kar je mišljeno ((DataH << 8) + DataL), vendar je brez preverjanja rezultata prevajalnika take stvari zelo nespametno uporabljati - sigurno so tu še problemi z big endian / little endian sistemi ...
Jaz bi rekel, da gre tukaj za eno zelo nepametno in nepotrebno optimizacijo, ki je - razen v primeru da se izvaja v res ozki zanki - popolnoma nepotrebna, glede na to, da je šiftanje ponavadi precej optimalno zakodirano v hardveru (en cikel) ...
Jaz bi že zaradi preglednosti volje naredil tako, kot je napisal Sokrat, paziti je potrebno pa, ker so dataH in dataL tipa char, da je mogoče pred operacijo potrebno ti dve spremenljivki typecast-at v unsigned int.
LP! |
|
Nazaj na vrh |
|
 |
chaos Član


Pridružen-a: Sob 16 Sep 2006 22:12 Prispevkov: 1063 Aktiv.: 4.66 Kraj: Zagorje ob Savi
|
Objavljeno: Sob Avg 22, 2009 3:12 pm Naslov sporočila: |
|
|
No, sem si vzel pet minut in preizkusil vse tri variante - vse vrnejo pravi rezultat, najhitrejša je verjetno originalna, druga je varianta od sokrata, najpočasnejša bi lahko bilo z množenjem, razen če je prevajalnik tako pameten, da vidi, da lahko namesto množenja uporabi šiftanje:
Koda: |
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned int sdata1;
unsigned int sdata2;
unsigned int sdata3;
unsigned int data_hi;
unsigned int data_lo;
data_lo = 0xcd;
data_hi = 0xab;
sdata1 = 256*data_hi + data_lo;
sdata2 = (data_hi<<0x8) | data_lo;
sdata3 = 0;
*((unsigned char *)(&sdata3)) = data_lo;
*((unsigned char *)(&sdata3)+1) = data_hi;
if ( (sdata1 != 0xabcd) || (sdata2 != 0xabcd) || (sdata3 != 0xabcd) ) {
printf("One of the calculations is wrong!\n");
return -1;
}
printf("sdata1 (multiply+add) 0x%04x\n", sdata1);
printf("sdata2 (shift+or) 0x%04x\n", sdata2);
printf("sdata3 (pointers) 0x%04x\n", sdata3);
return 0;
}
|
LP! |
|
Nazaj na vrh |
|
 |
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 494 dni
Powered by phpBB © 2001, 2005 phpBB Group
|