RTV forum PL | NewsGroups PL

Dziwne odczyty i zachowanie kompilatora AVRGCC przy pracy z progmem w C?

Dziwne zachowanie kompilatora w AVRGCC.

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Dziwne odczyty i zachowanie kompilatora AVRGCC przy pracy z progmem w C?

Goto page 1, 2, 3, 4, 5, 6, 7  Next

Milosz Skowyra
Guest

Tue May 04, 2004 10:59 pm   



Ehlo.

Jako ze guru wiedzy na temat C jeszcze nie jestem (ale zamierzam Wink))
), wynalazlem pewien problem ktory mnie meczy. Mianowicie w programie
definiuje znaki LCD za w nastepujacy sposob:

definicje znakow:

static unsigned char __attribute__ ((progmem)) polish_chars[]={
0x0C,0x04,0x06,0x0C,0x04,0x04,0x0E,0x00, //0 - l
[...]
0x00,0x04,0x0E,0x10,0x10,0x11,0x0E,0x00}; //5 = c


for (unsigned char f=1;f<64;f++)
{
lcd_port=pgm_read_byte(&polish_chars+f);
data_port |= (unsigned char)_BV(rs);
nop();nop();nop();
data_port |= (unsigned char)_BV(en);
nop();nop();nop();
data_port &= (unsigned char)~_BV(en);
data_port &= (unsigned char)~_BV(rs);
lcd_delay_short();
}

No i problem. Mianowicie wartosc wyliczona przez (&polish_chars+f) w
pierwszym odczycie daje poprawnie wartosc 0x22, jednak w kolejnym kroku
kompilator zwieksza Z nie o jeden jak powinien lecz o 0x31 (cos jakby
wartosc '1' w ASCII). Popelniam jakis blad ??

Za to ten programik dziala poprawnie. Z jest zwiekszane o 0x01.

unsigned char f=0;
int g;
g=(&polish_chars);
while (f<64)
{
lcd_port=pgm_read_byte(g+f);
data_port |= (unsigned char)_BV(rs);
nop();nop();nop();
data_port |= (unsigned char)_BV(en);
nop();nop();nop();
data_port &= (unsigned char)~_BV(en);
data_port &= (unsigned char)~_BV(rs);
lcd_delay_short();
f++;
}

Moze mi ktos wytlumaczyc czy to ja robie zle czy co ? Z gorki dzieki.

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Milosz Skowyra
Guest

Tue May 04, 2004 11:24 pm   



Milosz Skowyra wrote:

Juz sam wiem, olalem warninga kompilatora i zapomnialem o zrzutowaniu
wskaznika na integera ;-)

Quote:
lcd_port=pgm_read_byte(&polish_chars+f);
powinno byc

lcd_port=pgm_read_byte(((int)&polish_chars)+f);
I dziala ;-)

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Andy
Guest

Wed May 05, 2004 12:56 am   



Użytkownik "Milosz Skowyra" <mewashek@wp.pl> napisał w wiadomości
news:40982E77.75A88955@wp.pl...
Quote:
...
static unsigned char __attribute__ ((progmem)) polish_chars[]={
0x0C,0x04,0x06,0x0C,0x04,0x04,0x0E,0x00, //0 - l
[...]
0x00,0x04,0x0E,0x10,0x10,0x11,0x0E,0x00}; //5 = c


for (unsigned char f=1;f<64;f++)
{
lcd_port=pgm_read_byte(&polish_chars+f);
...

a nie mogl bys tej tablicy jakos po ludzku indeksowac ? :-)

polish_chars[ f ]

tak jest chyba najbardziej naturalnie

--
Andrzej

Krzysztof Rudnik
Guest

Wed May 05, 2004 4:25 am   



Milosz Skowyra wrote:

Quote:
Ehlo.

Jako ze guru wiedzy na temat C jeszcze nie jestem (ale zamierzam Wink))
), wynalazlem pewien problem ktory mnie meczy. Mianowicie w programie
definiuje znaki LCD za w nastepujacy sposob:

definicje znakow:

static unsigned char __attribute__ ((progmem)) polish_chars[]={
0x0C,0x04,0x06,0x0C,0x04,0x04,0x0E,0x00, //0 - l
[...]
0x00,0x04,0x0E,0x10,0x10,0x11,0x0E,0x00}; //5 = c


for (unsigned char f=1;f<64;f++)
{
lcd_port=pgm_read_byte(&polish_chars+f);
data_port |= (unsigned char)_BV(rs);
nop();nop();nop();
data_port |= (unsigned char)_BV(en);
nop();nop();nop();
data_port &= (unsigned char)~_BV(en);
data_port &= (unsigned char)~_BV(rs);
lcd_delay_short();
}

No i problem. Mianowicie wartosc wyliczona przez (&polish_chars+f) w

- w takim ukladzie moze ci adrument zwiekszac w sizeof(polish_chars),
wyrzuc ten &. Wtedy argumentami pgm_read_byte beda kolejne adresy
zaczynajac od &polish_chars[f]. Mozna tez tak zapisac. W C
dodanie liczby n do pointera tworzy pointer przesuniety o
n - elementow tablicy. Ty dodajesz liczba do adresu calej tablicy,
a nie do adresu jej pierwszego elementu.

Podsumowujac:

&polish_chars[f] - adres f-tego elementu tablicy
polish_chars+f - tyle samo

&polish_chars+f - adres f-tej tablicy

Krzysiek Rudnik

Tomq
Guest

Wed May 05, 2004 5:38 am   



Quote:
Juz sam wiem, olalem warninga kompilatora i zapomnialem o zrzutowaniu
wskaznika na integera Wink
lcd_port=pgm_read_byte(&polish_chars+f);
powinno byc
lcd_port=pgm_read_byte(((int)&polish_chars)+f);

nie jestem specem, ale kiedyś chciałbym być. proszę mnie oświecić
dlaczwgo "int" ? przecież tablica była definiowana jako "unsigned char"
"f" również, skąd i po co " int " ?

J.F.
Guest

Wed May 05, 2004 9:32 am   



On Wed, 5 May 2004 08:38:28 +0200, Tomq wrote:
Quote:
Juz sam wiem, olalem warninga kompilatora i zapomnialem o zrzutowaniu
wskaznika na integera Wink
lcd_port=pgm_read_byte(&polish_chars+f);
powinno byc
lcd_port=pgm_read_byte(((int)&polish_chars)+f);

nie jestem specem, ale kiedyś chciałbym być. proszę mnie oświecić
dlaczwgo "int" ? przecież tablica była definiowana jako "unsigned char"
"f" również, skąd i po co " int " ?

Bo sa dwa problemy:
a) .. '51 .. kto wie jaki rozmiar ma wskaznik, byc moze tylko
1 bajt ? Wiec wskaznik plus char moze sie ograniczac do 256.

b) kolega przekombinowal [a raczej nie przeczytal pewnej ksiazki Smile]
polish_chars+f powinno dzialac dobrze.
ale &polish_chars wskazuje na cala tablice i ma rozmiar jej calej,
wiec &polish_chars+1 to adres calej kolejnej tablicy, a nie
drugiego elementu ..

J.

Milosz Skowyra
Guest

Wed May 05, 2004 12:09 pm   



"J.F." wrote:

Quote:
b) kolega przekombinowal [a raczej nie przeczytal pewnej ksiazki Smile]

Czytam powoli... i podpieram sie dodatkowo kieszonkowym leksykonem C++.
Tyle tylko ze nie dopisalem kontekstu programu. Po prostu mam tablic
definicji znakow kilka i dodatkowo sa troche porozrzucane po flashu.
Korzystajac z jednej procedury chce wczytac jedna wybrana z nich.
Dlatego tak mi bylo wygodniej. Poza tym ten zapis jest dla mnie bardziej
czytelny. Ale moze sie myle. Ja go rozumiem tak:
pgm_read_byte(((int)&polish_chars)+f); odczytaj z pamieci ROM bajt z
adresu (gdzie adres=adres poczatku tablicy polish_chars, powiekszony o
f). Poniewaz pgm_read_byte() operuje na int to rzutuje polish_char na
inta i dodaje f jako char-a. W programie dla jednej tablicy co prawda
wystarczylby char, ale dla kilku juz nie ;-)

Quote:
polish_chars+f powinno dzialac dobrze.

Dziala, zezarl 20 bajtow wiecej ;-)

Quote:
ale &polish_chars wskazuje na cala tablice i ma rozmiar jej calej,

Zaraz... bo sie pogubilem. Zalozmy ze mam tablice char tab[20];
I teraz zeby dostac sie do 10 elementu moge uzyc:
a) char x=tab[9]
b) Znalezc adres tablicy i dodac offset czyli char x=(((int)&tab)+10);
c) Wskaznik na poczatek tablicy i zwiekszyc go o 10 i odczytac. char *x;
*x=&polish_chars; *x+=10;

Jesli jest tak jak piszesz o rozmiarze to dlaczego sizeof(&polish_chars)
daje 2 ? To znaczy dla mnie to jasne bo wynikiem jest adres ktory jest
integerem wiec ma rozmiar 2. Myle sie ??

Quote:
wiec &polish_chars+1 to adres calej kolejnej tablicy, a nie
drugiego elementu ..

Tu sie zgodze.

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Milosz Skowyra
Guest

Wed May 05, 2004 12:19 pm   



Andy wrote:

Quote:
a nie mogl bys tej tablicy jakos po ludzku indeksowac ? Smile
polish_chars[ f ]
tak jest chyba najbardziej naturalnie

Tylko ze nie bardzo chce dzialac Wink
W R14 i R15 jest adres poczatku tablicy.

MOV R31,R15
MOV R30,R14 ;to niby poprawnie, do Z wpisuje pocz.tablicy
LD R24,Z+ ;w dziwny sposob zwieksza Z o jeden i czyta
;bajt z RAMU spod adresu poczatku tablicy w ROM
MOV R14,R30 ;zrzuca adres tablicy +1
MOV R15,R31
MOV R30,R24 ;i gdyby nie wykonal tego to LPM odczytalo by
CLR R31 ;poprawna wartosc, a tak dostajemy krzaczki.
LPM

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Milosz Skowyra
Guest

Wed May 05, 2004 12:23 pm   



Krzysztof Rudnik wrote:

Quote:
No i problem. Mianowicie wartosc wyliczona przez (&polish_chars+f) w
- w takim ukladzie moze ci adrument zwiekszac w sizeof(polish_chars),
wyrzuc ten &. Wtedy argumentami pgm_read_byte beda kolejne adresy
zaczynajac od &polish_chars[f]. Mozna tez tak zapisac. W C
dodanie liczby n do pointera tworzy pointer przesuniety o
n - elementow tablicy. Ty dodajesz liczba do adresu calej tablicy,
a nie do adresu jej pierwszego elementu.

Zgadza sie. Co prawda po przeczytaniu kilku postow mam maly metlik, ale
sprobuje usystematyzowac.
&polish_chars - to adres poczatku tablicy.
Jesli zrobie *x=&polish_chars to wskaznik *x wskazuje na poczatek
tablicy.
Poprawnie ??

Quote:
Podsumowujac:

&polish_chars[f] - adres f-tego elementu tablicy
polish_chars+f - tyle samo
&polish_chars+f - adres f-tej tablicy

Dzieki... dobrze mysle tylko nie potrafie tego jeszcze dobrze w C
zapisac ;-(

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

J.F.
Guest

Wed May 05, 2004 1:59 pm   



On Wed, 05 May 2004 15:19:30 +0200, Milosz Skowyra wrote:
Quote:
Andy wrote:
a nie mogl bys tej tablicy jakos po ludzku indeksowac ? Smile
polish_chars[ f ]

Tylko ze nie bardzo chce dzialac Wink
W R14 i R15 jest adres poczatku tablicy.

MOV R31,R15
MOV R30,R14 ;to niby poprawnie, do Z wpisuje pocz.tablicy
LD R24,Z+ ;w dziwny sposob zwieksza Z o jeden i czyta

Ta dziwnosc moze byc sprytnoscia - jesli rozpoznal ze w kolejnych
obiegach petli siegasz do kolejnych komorek pamieci, to jest
to prawidlowa kompilacja.

Quote:
;bajt z RAMU spod adresu poczatku tablicy w ROM
MOV R14,R30 ;zrzuca adres tablicy +1
MOV R15,R31
MOV R30,R24 ;i gdyby nie wykonal tego to LPM odczytalo by
CLR R31 ;poprawna wartosc, a tak dostajemy krzaczki.
LPM

A nie przekombinowales znowu ? Moze masz
lcd_port=pgm_read_byte(polish_chars[f]);

J.

J.F.
Guest

Wed May 05, 2004 1:59 pm   



On Wed, 05 May 2004 15:09:37 +0200, Milosz Skowyra wrote:
Quote:
"J.F." wrote:
b) kolega przekombinowal [a raczej nie przeczytal pewnej ksiazki Smile]
Czytam powoli... i podpieram sie dodatkowo kieszonkowym leksykonem C++.

Czytac szybciej, szczegolnie rozdzial arytmetyka wskaznikow :-)

Ogolnie C dziala tak, ze (wsk+liczba) ma wartosc liczbowa
adres(wsk) + liczba*sizeof(*wskaznik)

Innymi slowy - trzeba pilnie uwazac na typ na ktory wskaznik wskazuje,
bowiem dodajemy rozne wartosci. Ale to jest dla wygody, dzieki temu
t[i] jest dokladnie tym samym co *(t+i)

Quote:
Ja go rozumiem tak:
pgm_read_byte(((int)&polish_chars)+f); odczytaj z pamieci ROM bajt z
adresu (gdzie adres=adres poczatku tablicy polish_chars, powiekszony o f).

Owszem, z tym ze :
- wystarczy pgm_read_byte(((int)polish_chars)+f) -
polish_chars i &polish_chars to sa te same adresy, roznia
sie natomiast wielkoscia obiektu wskazywanego [co tu nie ma
znaczenia]

- w innym procku relacje miedzy wskaznikiem a integerem moga byc
inne, wiec zaleca sie nie dokonywac takiej konwersji.

- akurat w AVR byc moze ta funkcja faktycznie ma parametr int,
a nie char*.

Quote:
polish_chars+f powinno dzialac dobrze.
Dziala, zezarl 20 bajtow wiecej Wink

A to ciekawe. Zglos moze te uwagi supportowi, moze poprawia.

Quote:
Zaraz... bo sie pogubilem. Zalozmy ze mam tablice char tab[20];
I teraz zeby dostac sie do 10 elementu moge uzyc:
a) char x=tab[9]
b) Znalezc adres tablicy i dodac offset czyli char x=(((int)&tab)+10);

Nie - tak to oliczyles adres [zly!], nie pobrales natomiast
zlokalizowanej tam danej, czemu sluzy *

x=*(((int)&tab)+9)
a dokladniej, to by wypadalo napisac

x=*( (char*) (((int)&tab)+9));

to samo moglbys zapisac jako

x=*( (char*) (((int)tab)+9));
x=*( tab+9 );

Czy nawet 9[x] - co z definicji wynosi *(9+tab)

Quote:
c) Wskaznik na poczatek tablicy i zwiekszyc go o 10 i odczytac. char *x;
*x=&polish_chars; *x+=10;

Tu glupoty jakies piszes:-)

char *x;

OK, x jest wskaznikiem, czyli adresem, komorki pamieci zawierajacej
znak. x jest oczywiscie zmienna, czyli zajmuje dwa bajty w tym procku.
x chwilowo jest niezainicjowany, czyli wskazuje w losowo wybrane
miejsce pamieci [starsze C wymagaly zeby takie zmienne globalne
byly wstepnie zerowane].

*x=&polish_chars;

To jest glupota totalna, bo w ten jeden znak _wskazywany_ przez x
[czyli chwilowo w jakies losowe miejsce w pamieci Smile] usilujesz
wpisac adres tablicy - czyli pewnie tylko mlodszy bajt adresu.

*x+=10;

A niniejszym usilujesz do znaku wskazywanego przez x dodac 10.

Z sensem wygladaloby to tak:

char *x; //wskaznik
x=&polish_chars; //teraz wskazuje na poczatek tablicy
x+=3 //teraz wskazuje na 4 znak tablicy
*x+=5 // a teraz ten znak powiekszamy o 5

Gdyby w tablicy bylo "ABCDEFGHI", to po wykonaniu zrobiloby sie
"ABCIEFGHI" ... gdyby to nie byl ROM.

Quote:
Jesli jest tak jak piszesz o rozmiarze to dlaczego sizeof(&polish_chars)
daje 2 ? To znaczy dla mnie to jasne bo wynikiem jest adres ktory jest
integerem wiec ma rozmiar 2. Myle sie ??

Bo polish_chars jest tablica, i rozmiar ma chocby i 64.
Ale &polish_chars jest juz tylko adresem, a ten liczy 2 bajty.

Natomiast kompilator pamieta na co &polish_chars wskazuje,
wiec &polish_chars+1 to bynajmniej nie jest ten sam adres
co polish_chars+1.

Nawiasem mowiac - moglbys to zrobic tak:

char * dp;

dp=polish_chars; // lub jak wolisz dp=&polish_chars ;
for (unsigned char f=1;f<64;f++)
{
lcd_port=pgm_read_byte(dp);
dp++;
// lub wrecz lcd_port=pgm_read_byte(dp++);

data_port |= (unsigned char)_BV(rs); [...]
}

Tracisz 2 bajty RAM na dodatkowa zmienna [zreszta niekoniecznie], ale
byc moze zyskujesz cos na programie - o ile powiekszenie wskaznika
jest w danym procku prostsza operacja niz dodanie dwoch liczb 16 bit..


A swoja droga - o ile kompilator pozwala zdefiniowac taka tablice
w obszarze pgm, to imho powinien poprawnie komplilowac po prostu
polish_chars[f] - albo cos o tym pisze w faq, albo trzeba serwis
powiadomic..

J.

Jan Dubiec
Guest

Wed May 05, 2004 2:54 pm   



On Wed, 05 May 2004 16:59:19 +0200, J.F. <jfox_nospam@poczta.onet.pl> wrote:
Quote:
On Wed, 05 May 2004 15:09:37 +0200, Milosz Skowyra wrote:
[.....]
Owszem, z tym ze :
- wystarczy pgm_read_byte(((int)polish_chars)+f) -
polish_chars i &polish_chars to sa te same adresy, roznia
sie natomiast wielkoscia obiektu wskazywanego [co tu nie ma
znaczenia]
Na mój gust to są dwa różne adresy - polish_chars jest adresem obszaru

pamięci w którym umieszczone są obiekty typu char (czyli polish_chars
to jest po prostu typu char *), natomiast &polish_chars jest adresem adresu
w/w obszaru czyli mówiąc inaczej jest typu char **, albo jescze inaczej,
jest wskaźnikiem na wskaźnik. :-)

[.....]
Quote:
Zaraz... bo sie pogubilem. Zalozmy ze mam tablice char tab[20];
I teraz zeby dostac sie do 10 elementu moge uzyc:
a) char x=tab[9]
b) Znalezc adres tablicy i dodac offset czyli char x=(((int)&tab)+10);

Nie - tak to oliczyles adres [zly!], nie pobrales natomiast
zlokalizowanej tam danej, czemu sluzy *

x=*(((int)&tab)+9)
a dokladniej, to by wypadalo napisac

x=*( (char*) (((int)&tab)+9));
Nie chce mi się odpalać kompilatora ale jestem pewien że żadna z

powyższych konstrukcji nie zadziała tak jak oczekiwano. :-)

Quote:
to samo moglbys zapisac jako

x=*( (char*) (((int)tab)+9));
x=*( tab+9 );
Drugie wyrażenie będzie działać, pierwsze nie zawsze. Ale one nie są

równoważne tym dwóm wcześniejszym.

Poza tym w zasadzie warto byłoby sprecyzować w tej dyskusji (i w
świetle tego co napisałem na samym początku) co to znaczy "znaleźć
adres tablicy". Bo jeśli chodzi o adres obszar pamięci w którym
znajdują się przechowywane obiekty, to wartość zmiennej tab (pisanej
bez żadnych indeksów) jest właśnie tym adresem i nic nie trzeba
szukać.

[.....]
Quote:
Z sensem wygladaloby to tak:

char *x; //wskaznik
x=&polish_chars; //teraz wskazuje na poczatek tablicy
^- powinno być tez tego ampersanda
x+=3 //teraz wskazuje na 4 znak tablicy
*x+=5 // a teraz ten znak powiekszamy o 5

Regards,
/J.D.
--
Jan Dubiec, jdx@slackware.pl, mobile: +48 506 790442

Głęboka wiara wymaga płytkiego rozumu i nikłej wiedzy.

J.F.
Guest

Wed May 05, 2004 4:45 pm   



On 05 May 2004 17:54:28 +0200, Jan Dubiec wrote:
Quote:
On Wed, 05 May 2004 16:59:19 +0200, J.F. <jfox_nospam@poczta.onet.pl> wrote:
- wystarczy pgm_read_byte(((int)polish_chars)+f) -
polish_chars i &polish_chars to sa te same adresy, roznia
sie natomiast wielkoscia obiektu wskazywanego [co tu nie ma
znaczenia]
Na mój gust to są dwa różne adresy - polish_chars jest adresem obszaru
pamięci w którym umieszczone są obiekty typu char (czyli polish_chars
to jest po prostu typu char *), natomiast &polish_chars jest adresem adresu
w/w obszaru czyli mówiąc inaczej jest typu char **, albo jescze inaczej,
jest wskaźnikiem na wskaźnik. Smile

Nie - pamietaj ze polish_chars jest tablica !
wiec "jej wartosc liczbowa" jest adresem pierwszego elementu, i
pokrywa sie z adresem calosci.

Quote:
[.....]
Zaraz... bo sie pogubilem. Zalozmy ze mam tablice char tab[20];
I teraz zeby dostac sie do 10 elementu moge uzyc:
a) char x=tab[9]
b) Znalezc adres tablicy i dodac offset czyli char x=(((int)&tab)+10);

Nie - tak to oliczyles adres [zly!], nie pobrales natomiast
zlokalizowanej tam danej, czemu sluzy *

x=*(((int)&tab)+9)
a dokladniej, to by wypadalo napisac

x=*( (char*) (((int)&tab)+9));

Nie chce mi się odpalać kompilatora ale jestem pewien że żadna z
powyższych konstrukcji nie zadziała tak jak oczekiwano. Smile


Powinny.

Quote:
to samo moglbys zapisac jako
x=*( (char*) (((int)tab)+9));
x=*( tab+9 );
Drugie wyrażenie będzie działać, pierwsze nie zawsze.

Zgodze sie - potrafia byc niuanse. Ale czesto int sie pokrywa
ze wskaznikiem - i wtedy powinno zadzialac.

Quote:
Ale one nie są równoważne tym dwóm wcześniejszym.

Poza tym drobnym zastrzezeniem - sa.

Quote:
Poza tym w zasadzie warto byłoby sprecyzować w tej dyskusji (i w
świetle tego co napisałem na samym początku) co to znaczy "znaleźć
adres tablicy". Bo jeśli chodzi o adres obszar pamięci w którym
znajdują się przechowywane obiekty, to wartość zmiennej tab (pisanej
bez żadnych indeksów) jest właśnie tym adresem i nic nie trzeba
szukać.

Dokladnie. Wiec tab==&tab - choc sa miedzy nimi roznice typu
i nie zachowuja sie tak samo.

Aha - to dotyczy rzeczywistej deklaracji tablicy, bo
deklaracja w naglowku funkcji jest wskaznikiem..


J.

Jan Dubiec
Guest

Wed May 05, 2004 6:17 pm   



On Wed, 05 May 2004 19:45:58 +0200, J.F. <jfox_nospam@poczta.onet.pl> wrote:
Quote:
On 05 May 2004 17:54:28 +0200, Jan Dubiec wrote:
On Wed, 05 May 2004 16:59:19 +0200, J.F. <jfox_nospam@poczta.onet.pl> wrote:
- wystarczy pgm_read_byte(((int)polish_chars)+f) -
polish_chars i &polish_chars to sa te same adresy, roznia
sie natomiast wielkoscia obiektu wskazywanego [co tu nie ma
znaczenia]
Na mój gust to są dwa różne adresy - polish_chars jest adresem obszaru
pamięci w którym umieszczone są obiekty typu char (czyli polish_chars
to jest po prostu typu char *), natomiast &polish_chars jest adresem adresu
w/w obszaru czyli mówiąc inaczej jest typu char **, albo jescze inaczej,
jest wskaźnikiem na wskaźnik. :-)

Nie - pamietaj ze polish_chars jest tablica !
wiec "jej wartosc liczbowa" jest adresem pierwszego elementu, i
pokrywa sie z adresem calosci.
[.....]
Dokladnie. Wiec tab==&tab - choc sa miedzy nimi roznice typu
i nie zachowuja sie tak samo.
Rzeczywiście, masz rację co widać na załączonym przykładzie:


#include <stdio.h>

int main(int argc, char **argv)
{
char tab1[10], *tab2, **tp1, **tp2;

tp1 = (char**) &tab1;
tp2 = &tab2;
printf("tab1=%p, tp1=%p, *tp1=%p\n", tab1, tp1, *tp1);
printf("tab2=%p, tp2=%p, *tp2=%p\n", tab2, tp2, *tp2);

tab2 = tab1;
printf("tab2=%p, tp2=%p, *tp2=%p\n", tab2, tp2, *tp2);

return 0;
}

Niby do tab1 i tab2 można odwoływać się w ten sam sposób, tj. przy pomocy
indeksów lub arytmetyki wskaźników ale jednak są pewne niuanse w działaniu
operatora &. Smile Używając C trzeba być jednak czujnym przez cały czas. :-)

Quote:
Aha - to dotyczy rzeczywistej deklaracji tablicy, bo
deklaracja w naglowku funkcji jest wskaznikiem..
Nie bardzo rozumiem. Może jakiś przykład?


Regards,
/J.D.
--
Jan Dubiec, jdx@slackware.pl, mobile: +48 506 790442

Głęboka wiara wymaga płytkiego rozumu i nikłej wiedzy.

Piotr Wyderski
Guest

Wed May 05, 2004 7:08 pm   



Milosz Skowyra wrote:

Quote:
for (unsigned char f=1;f<64;f++)

Wiesz, w C tablice indeksuje sie poczynajac od 0. Smile
Poza tym postinkrementacji nalezy uzywac tylko gdy
naprawde trzeba; w przeciwnym przypadku nalezy
uzyc preinkrementacji: ++f. W tym przypadku nie
ma to znaczenia, ale jesli zaczniesz programowac w
C++, to zobaczysz roznice, gdy sobie przeciazysz ++.

Quote:
No i problem. Mianowicie wartosc wyliczona przez (&polish_chars+f) w
pierwszym odczycie daje poprawnie wartosc 0x22, jednak w kolejnym kroku
kompilator zwieksza Z nie o jeden jak powinien lecz o 0x31 (cos jakby
wartosc '1' w ASCII). Popelniam jakis blad ??

Scisle rzecz biorac nie popelniasz bledu, ale napisales
kompilatorowi nie ten program o ktorym myslales. Smile
Kazesz mu wziac adres poczatku f-tej _tablicy_, a
nie adres f-tego _elementu_ tej tablicy. Natomiast to
0x31 do niczego mi nie pasuje: masz 49 elementow w tablicy?

Quote:
unsigned char f=0;
int g;
g=(&polish_chars);

No chyba zartujesz. Smile Dlaczego nie uzyjesz

const unsigned char* g = polish_chars;

?

Pozdrawiam
Piotr Wyderski

PS. Cos wspominales o przejsciu na uprawe marchewki. Wink))

Goto page 1, 2, 3, 4, 5, 6, 7  Next

elektroda NewsGroups Forum Index - Elektronika Polska - Dziwne odczyty i zachowanie kompilatora AVRGCC przy pracy z progmem w C?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map