Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

Wskaźnik do tablicy dwuwymiarowej w C (dla AVR-GCC)

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:
Wskaźnik do tablicy dwuwymiarowej w C (dla AVR-GCC)

Postautor: Sławek5 » 23 cze 2007, o 18:43

CZeść.
Chciałem Was prosić o pmoc w zrozumieniu takiej rzeczy.
Powiedzmy że mam w C zadeklarowaną taką tablicę dwuwymairową:

Kod: Zaznacz cały

byte Font[7][5] = { { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x2f, 0x00, 0x00 }, { 0x00, 0x07, 0x00, 0x07, 0x00 }, { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, { 0xc4, 0xc8, 0x10, 0x26, 0x46 }, { 0x36, 0x49, 0x55, 0x22, 0x50 } };


CZy to jest rozumiane jako tablica 7 elemetów zbudowanych z tablic 5 eementowych?

A teraz dostęp przez wskaźnik:

Kod: Zaznacz cały

byte *wsk=Font[3];
Dlaczego przy przypisaniu do wsaźnika jest tylko jeden nawias, czy on oznacza 4 wiersz. Czyli do wsk zostaje przypisany aderes pierwszego elementu w (pierwsza kolumna) w 4 wierszu.
A jak teraz za pomocą tego wskaźnika poruszać sie po tej tablicy Font?

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty:2653
Rejestracja:24 sty 2005, o 00:39
Lokalizacja:Winny gród

Re: Wskaźnik do tablicy dwuwymiarowej w C (dla AVR-GCC)

Postautor: pajaczek » 23 cze 2007, o 22:33

CZy to jest rozumiane jako tablica 7 elemetów zbudowanych z tablic 5 eementowych?
Tak, mozna to tak rozumiec.
Dlaczego przy przypisaniu do wsaźnika jest tylko jeden nawias, czy on oznacza 4 wiersz. Czyli do wsk zostaje przypisany aderes pierwszego elementu w (pierwsza kolumna) w 4 wierszu.
Gdyz iz ;) Font jest tablica tablic... inaczej mowiac sklada sie z elementow typu tablica, co implikuje fakt ze pod elementem [3] znajduje sie poczatek 4-go elementu tablicy, ktory jest... tablica, wskaznik jest wskaznikiem na byte, a wiec oczekujemy tylko 1 bajta danych.
Mozesz sie dobrac do nastepnych np. przez

Kod: Zaznacz cały

byte *wsk=Font[3]+3; //albo byte liczba=*(Font[0]+2);
gdy chcesz uzyskac 4 wiersz, 4 kolumne, oraz 1 wiersz, 3 kolumne.

Ale jeszcze uwaga, bo

Kod: Zaznacz cały

byte *wsk=Font[0]+15; //oraz byte *wsk=Font[1]+10;
tez da Ci dostep do 4 wiersza, 1 elementu :619:

Zweryfikuj to, bo sprawdzalem to jedynie pod gcc x86

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 24 cze 2007, o 07:05

A jeszcz taka sprawa.
Jeśli mam tablice jednowymarową np byte tablica[10]; to jeśli chcę stworzyć tablce dwuwymarową złożoną z 3 elemetów tablica[10] to dlaczego ten indeks wierszy jest niby najbadziez z jewej.. bo np jak mam zmienną byte a; to jak tworzę tabicę do nawiasy są dopisywane z prawej strony i piszemy byte a[10]; a nie byte [10]a - bez sensu.
Więc idąc ctym tropem powinno się napisać byte tablica[10][3] a tu jednak piszemy
tablica[3[10]. Podobno jest jakaś w tym prawidłowość i może wiesz jaka?

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty:2653
Rejestracja:24 sty 2005, o 00:39
Lokalizacja:Winny gród

Postautor: pajaczek » 24 cze 2007, o 12:34

Rozwiazywanie jakichkolwiek zmiennych w C zaczynasz od nazwy, idziesz w prawo do napotkania nawiasu badz srednika....

tutaj bedzie to wygladac tak

1) tablica - nasza zmienna

2) tablica[] - zmienna jest tablica

3) tablica[3] - zmienna jest tablica 3 elementowa

4) tablica[3][] - zmienna jest tablica 3 elementowa, skladajaca sie z tablic

5) tablica[3][10] - zmienna jest tablica 3 elementowa, skladajaca sie z tablic 10 elementowych

6) tablica[3][10]; - zmienna jest tablica 3 elementowa, skladajaca sie z tablic 10 elementowych, srednik, a wiec zawracamy w interpretacji

7) byte tablica[3][10]; - zmienna jest tablica 3 elementowa, skladajaca sie z tablic 10 elementowych, skladajacych sie z typu byte


Koniec przetwarzania....

nieco bardziej skomplikowanie wyglada to w niektorych innych przypadkach, np. sprobuj rozwiazac co to jest:

int *(*znak[4])(int *);


Ps. To ze tablica ma "wiersze" i "kolumny" to jest sprawa umowna... rownie dobrze mozesz zmienic nomenklature nazw i to co nazywasz "wierszami" nazwac "komumntami" i odwrotnie... tak naprawde to jest to poprostu szereg x kolejnych obszarow pamieci wielkosci elementu y, ktory to element jest y kolejnych obszarow wielkosci byte (w Twoim przypadku). Nie jest to zaden twor 2 wymiarowy (czy x wymiarowy w ogolnosci), lecz kolejnych x*y komorek typu byte. Dzieki temu mozesz sie dobrac do 3 rzedu dodajac cos do wskaznika wskazujacego na pierwszy (np. *wsk wskazuje na 1 rzad, tablica to byte[3][5], *(wsk+10) bedzie wskazywal na rzad 3-ci (pierwszy element tego "rzedu"). Co ciwkawe, mozna tez odejmowac ;p
W calej tej zabawie ze wskaznikami nalezy jedynie uwazac by nie "wyjsc" poza obszar nas interesujacy, bo moga zaczac wychodzic bzdury... np. jak odejmiesz 2 pozycje od wskaznika wskazujacego 3 element tablicy, to ok... ale jak odejmiesz 5?? to na co trafisz??

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 24 cze 2007, o 14:51

sprobuj rozwiazac co to jest:

int *(*znak[4])(int *);
Powiem szczerze że nie wiem co to jest. Sam bym nie napisał tego bo wydaje mi się dośc skomplikowane. Nawet nie wim jak to czytać.

P.S. Możesz polecić jakąś książkę ktora opisuje tego typu rzezczy? Ja mam kilka o C ale w żadnej nie spotkałem takiego opisu jaki Ty przedstawiasz, a on mi się podoba bo jest jasny i zrozumiały.

szymel
-
-
Posty:212
Rejestracja:16 sty 2005, o 16:42
Lokalizacja:Włocławek

Postautor: szymel » 24 cze 2007, o 16:25

sprobuj rozwiazac co to jest:

int *(*znak[4])(int *);
Powiem szczerze że nie wiem co to jest...
http://home.agh.edu.pl/~chwastek/lectures/C/tfdekl.html
Polecam cały ... "kurs" ;)
Przykładowy kod:

Kod: Zaznacz cały

#include <avr/io.h> int *f0(int *x) {return ++x;} int *f1(int *x) {return --x;} int *f2(int *x) {return x+5;} int *f3(int *x) {return x-5;} int *(*znak[4])(int *)={f0,f1,f2,f3}; int main() { int *(**ff)(int *) ; int x=15,*px=&x; ff=znak; px=(*ff++)(px); px=(*ff++)(px); px=(*ff++)(px); px=znak[3]((int*)x); for(;;); return 0; }
Ten C jest naprawdę "zakręcony" , ale jaki "wygodny" ;)
Piotrek

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty:2653
Rejestracja:24 sty 2005, o 00:39
Lokalizacja:Winny gród

Postautor: pajaczek » 24 cze 2007, o 19:55

sprobuj rozwiazac co to jest:

int *(*znak[4])(int *);
Powiem szczerze że nie wiem co to jest. Sam bym nie napisał tego bo wydaje mi się dośc skomplikowane. Nawet nie wim jak to czytać.

P.S. Możesz polecić jakąś książkę ktora opisuje tego typu rzezczy? Ja mam kilka o C ale w żadnej nie spotkałem takiego opisu jaki Ty przedstawiasz, a on mi się podoba bo jest jasny i zrozumiały.
Ten opis jest mojego autorstwa... :619: ale poza podanym przez Szymela (nie sprawdzalem), moge polecic Symfonie C++, fakt dotyczy C++ a nie C, jednak ten akurat aspekt sie pokrywa, a jest fajnie wytlumaczony.

A to co przedstawilem to 4 elementowa tablica wskaznikow do funkcji, przyjmujacych jako jedyny argument wskaznik do integera, i zwracajacej wskaznik do integera ;) Proste nie ;P A jakie przydatne :619:

Szymel:
No popatrz... jesli to jest z jakiegos kursu przyklad, to wyjatkowo sie z nim zgodzilem myslami ;p a taki sobie przyklad wymyslilem doslownie piszac tamten opis.
Btw. C/C++ nie sa wcale zakrecone... sa bardzo przejrzyste i wygodne. Fakt, jest sporo niuansow, ale to jest tylko ten dodatkowy urok.

Wróć do „AVR/AVR32”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 3 gości