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 

Relativno adresiranje polja strukture s pointerjem

 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Osnove programiranja AVR-jev
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
Tomazp
Član
Član



Pridružen-a: Sob 02 Feb 2008 13:24
Prispevkov: 559
Aktiv.: 2.64
Kraj: Ljubljana

PrispevekObjavljeno: Tor Maj 21, 2013 1:22 pm    Naslov sporočila:  Relativno adresiranje polja strukture s pointerjem Odgovori s citatom

Me zanima, če se da narediti naslednje. Imam strukturo v spodnjem primeru, do katere dostopam s pointerjem Če vsako polje naslavljam posamično z npr. ndata_x->p1 zadeva deluje. Kako bi naredil, da je ne bi naslavljal direktno z imenom polja temveč s spremenljivko npr. ndata_x->[i] ? Na ta način bi si prihranil veliko kode. Gre za proceduro urejanja nastavitvenih podatkov ki so kopirani iz eeproma in se update-tajo iz strukture nazaj.


Koda:
struct konfig {
char p1;
char p2;
char p3;
char p4;
char p5; 
char p6;
char p7;
char P8;
char P9;

};
struct konfig kn_data[4];

void urejanje(void)
{
struct konfig *ndata_x;

for (unsigned char i = 0; i < 9; i++)
   {


   ndata_x=&kn_data[n]; // n izbira kanala
   lcd_gotoxy(8,1);
   sprintf(msg,"K%01d P%02d",n,ndata_x->p1);
   lcd_puts(msg);
   }
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
.
Neznanec
Neznanec



Pridružen-a: Pet 01 Okt 2004 1:17
Prispevkov: 1
Aktiv.: 0.00

PrispevekObjavljeno: Tor Maj 21, 2013 1:34 pm    Naslov sporočila:   Odgovori s citatom

Brisana vsebina odstranjenega uporabnika.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Tomazp
Član
Član



Pridružen-a: Sob 02 Feb 2008 13:24
Prispevkov: 559
Aktiv.: 2.64
Kraj: Ljubljana

PrispevekObjavljeno: Tor Maj 21, 2013 1:41 pm    Naslov sporočila:   Odgovori s citatom

Hvala. Sedaj mi je prevedlo. Še preverim na vezju.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
gregoral
Član
Član



Pridružen-a: Pet 24 Nov 2006 9:42
Prispevkov: 688
Aktiv.: 3.04
Kraj: Ljubljana

PrispevekObjavljeno: Tor Maj 21, 2013 2:14 pm    Naslov sporočila:   Odgovori s citatom

Koda:
*(char*)(kndata_x+i)

Tole ne bo dobro!

Koda:
(kndata_x+i)

preskoči za celo strukturo naprej! (pomnoženo z i seveda)
V konkretnem primeru zelo verjetno za 8 ali 16 bytov zaradi poravnave!

Spremenljivke ki imajo več kot 1 byte so vedno poravnane na naslov ki je deljiv z N.
N je poravnava (alignment) in določa ali mora biti naslov deljiv z 1,2,4,8,16, ...

Zakaj?
Ker nekateri procesorji ne morejo delati recimo z int32 ki je na naslovu ki ni deljiv s 4.
Pri vseh procesorjih ki pa to podpirajo pa je dostop bistveno počasnejši!

Nekaj kar ima tudi nekaj slik na to temo:
Purpose of memory alignment
http://stackoverflow.com/questions/381244/purpose-of-memory-alignment

Takole bi bilo bolje:
Koda:
*((char*)kndata_x+i)

Seveda pa je tukaj zraven cel kup če-jev:
- p1 mora biti prvo polje
- slediti si morajo en za drugim
- prevajalnik jih mora zložti enega za drugim (največkrat je to tako, ni pa nujno)

Takole bo še bolje:
Koda:
*(&kndata_x->p1+i)

Tukaj imaš lahko pred p1 tudi druge spremenljivke.


Takole pa bi bilo še najbolje:
Koda:
struct konfig {
char p[9];
};

ndata_x->p[i] = 'A';



LP, Gregor
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Tomazp
Član
Član



Pridružen-a: Sob 02 Feb 2008 13:24
Prispevkov: 559
Aktiv.: 2.64
Kraj: Ljubljana

PrispevekObjavljeno: Tor Maj 21, 2013 3:13 pm    Naslov sporočila:   Odgovori s citatom

Hvala obema za pomoč in za izčrpno razlago. S kodo
Koda:
*(&ndata_x->p1+i)
mi sedaj lepo deluje. Tele pointerji so zares uporabni Very Happy .
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Tomazp
Član
Član



Pridružen-a: Sob 02 Feb 2008 13:24
Prispevkov: 559
Aktiv.: 2.64
Kraj: Ljubljana

PrispevekObjavljeno: Tor Maj 21, 2013 3:52 pm    Naslov sporočila:   Odgovori s citatom

Kako pa lahko samo vrednost spremenim? Direktno naslavljanje deluje
Koda:
++ndata_x->p1;
, indirektno pa mi ne gre:
Koda:
++ndata_x->p1+i;
in javlja, da izračunana vrednost ne bo upoštevana.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Tomazp
Član
Član



Pridružen-a: Sob 02 Feb 2008 13:24
Prispevkov: 559
Aktiv.: 2.64
Kraj: Ljubljana

PrispevekObjavljeno: Tor Maj 21, 2013 3:59 pm    Naslov sporočila:   Odgovori s citatom

Tudi spreminjanje deluje:

Koda:
++(*((char*)ndata_x+i));
Very Happy
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Osnove programiranja AVR-jev Č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: 493 dni


Powered by phpBB © 2001, 2005 phpBB Group