www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

problem s kazalci v C-ju

 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> AVR, LPC900, x51
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
damo
Član
Član



Pridružen-a: Čet 31 Jul 2003 13:45
Prispevkov: 2008
Aktiv.: 8.48
Kraj: Krško

PrispevekObjavljeno: Sob Avg 22, 2009 12:23 pm    Naslov sporočila:  problem s kazalci v C-ju Odgovori s citatom

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..... Sad )



mi lahko kdo razloži, kje je napaka? tile pointerji me vedno malo zmedejo...[/code]
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Sokrat
Član
Član



Pridružen-a: Čet 25 Avg 2005 11:00
Prispevkov: 5584
Aktiv.: 23.57

PrispevekObjavljeno: Sob Avg 22, 2009 12:40 pm    Naslov sporočila:   Odgovori s citatom

Zakaj pa sploh take komplikacije ? Think

Koda:
sdata = (DataH << 8) | DataL;

return sdata;

_________________
Ka ti bo pa torba ce si kupu kolo ?
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
damo
Član
Član



Pridružen-a: Čet 31 Jul 2003 13:45
Prispevkov: 2008
Aktiv.: 8.48
Kraj: Krško

PrispevekObjavljeno: Sob Avg 22, 2009 12:42 pm    Naslov sporočila:   Odgovori s citatom

ja, tisto s kazalci je bilo original. jaz sem dal namesto tega :dataL+256*dataH

vidim pa da je tvoj predlog še bolj optimiziran Wink
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Sokrat
Član
Član



Pridružen-a: Čet 25 Avg 2005 11:00
Prispevkov: 5584
Aktiv.: 23.57

PrispevekObjavljeno: Sob Avg 22, 2009 12:49 pm    Naslov sporočila:   Odgovori s citatom

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
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
damo
Član
Član



Pridružen-a: Čet 31 Jul 2003 13:45
Prispevkov: 2008
Aktiv.: 8.48
Kraj: Krško

PrispevekObjavljeno: Sob Avg 22, 2009 2:13 pm    Naslov sporočila:   Odgovori s citatom

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
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Sokrat
Član
Član



Pridružen-a: Čet 25 Avg 2005 11:00
Prispevkov: 5584
Aktiv.: 23.57

PrispevekObjavljeno: Sob Avg 22, 2009 2:40 pm    Naslov sporočila:   Odgovori s citatom

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
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.66
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Sob Avg 22, 2009 2:59 pm    Naslov sporočila:   Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.66
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Sob Avg 22, 2009 3:12 pm    Naslov sporočila:   Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> AVR, LPC900, x51 Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Stran 1 od 1

 
Pojdi na:  
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