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


Pridružen-a: Sob 02 Feb 2008 13:24 Prispevkov: 559 Aktiv.: 2.64 Kraj: Ljubljana
|
Objavljeno: Tor Maj 21, 2013 1:22 pm Naslov sporočila: Relativno adresiranje polja strukture s pointerjem |
|
|
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 |
|
 |
. Neznanec

Pridružen-a: Pet 01 Okt 2004 1:17 Prispevkov: 1 Aktiv.: 0.00
|
Objavljeno: Tor Maj 21, 2013 1:34 pm Naslov sporočila: |
|
|
Brisana vsebina odstranjenega uporabnika. |
|
Nazaj na vrh |
|
 |
Tomazp Član


Pridružen-a: Sob 02 Feb 2008 13:24 Prispevkov: 559 Aktiv.: 2.64 Kraj: Ljubljana
|
Objavljeno: Tor Maj 21, 2013 1:41 pm Naslov sporočila: |
|
|
Hvala. Sedaj mi je prevedlo. Še preverim na vezju. |
|
Nazaj na vrh |
|
 |
gregoral Član

Pridružen-a: Pet 24 Nov 2006 9:42 Prispevkov: 688 Aktiv.: 3.04 Kraj: Ljubljana
|
Objavljeno: Tor Maj 21, 2013 2:14 pm Naslov sporočila: |
|
|
Koda: |
*(char*)(kndata_x+i) |
Tole ne bo dobro!
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:
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 |
|
 |
Tomazp Član


Pridružen-a: Sob 02 Feb 2008 13:24 Prispevkov: 559 Aktiv.: 2.64 Kraj: Ljubljana
|
Objavljeno: Tor Maj 21, 2013 3:13 pm Naslov sporočila: |
|
|
Hvala obema za pomoč in za izčrpno razlago. S kodo
mi sedaj lepo deluje. Tele pointerji so zares uporabni . |
|
Nazaj na vrh |
|
 |
Tomazp Član


Pridružen-a: Sob 02 Feb 2008 13:24 Prispevkov: 559 Aktiv.: 2.64 Kraj: Ljubljana
|
Objavljeno: Tor Maj 21, 2013 3:52 pm Naslov sporočila: |
|
|
Kako pa lahko samo vrednost spremenim? Direktno naslavljanje deluje
, indirektno pa mi ne gre:
in javlja, da izračunana vrednost ne bo upoštevana. |
|
Nazaj na vrh |
|
 |
Tomazp Član


Pridružen-a: Sob 02 Feb 2008 13:24 Prispevkov: 559 Aktiv.: 2.64 Kraj: Ljubljana
|
Objavljeno: Tor Maj 21, 2013 3:59 pm Naslov sporočila: |
|
|
Tudi spreminjanje deluje:
Koda: |
++(*((char*)ndata_x+i)); |
 |
|
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: 493 dni
Powered by phpBB © 2001, 2005 phpBB Group
|