Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 9 mar 2021, o 01:04


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 25 ] 
Autor Wiadomość
 Tytuł: Wskaźniki
PostNapisane: 7 lut 2020, o 17:48 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 06 mar 2015
Posty: 157
Pomógł: 7

Witam.
Próbuję zmierzyć się ze wskaźnikami. Rozdział o wskaźnikach w BB, przeczytałem już naście razy i nadal tego nie ogarniam do końca.
Po krótce opiszę co wg. mnie (a przynajmniej tak mi się wydaje) już zrozumiałem a czego nie.
A więc tak:
Wskaźniki definiujemy podobnie jak inne zmienne, tyle że opatrzone są gwiazdką tak jak to jest opisane w BB np:
char *wsk;
int *wsk;
uint8_t *wsk;
czyli, najpierw zapisuję typ zmiennej a potem nazwę zmiennej poprzedzonej gwiazdką, która to informuje mnie, że nie jest to zwykła zmienna a wskaźnik na zmienną.
OK. To chyba zrozumiałem.
Przechodzimy teraz do zapisu.
Jeżeli zapiszę tak:
*wsk =10;
to powoduje, że do adresu gdzie zapisany jest ten wskaźnik, zostanie przypisana liczba 10.
Jeżeli chcemy żeby adres wskaźnika wskazywał na adres innej zmiennej, to piszemy tak:
wsk = x;
czyli wskaźnik wskazuje teraz na adres zmiennej x.
Jeżeli teraz chcemy zmienić wartość tej komórki x to znowu piszemy
*wsk = nowa wartość;
Kolejny krok.
Chcemy zawartość tego adresu przypisać do innej zmiennej to wykonujemy taki zapis:
nowa_zmienna = wsk;
I jeszcze jeden zapis:
wsk = &x;
Czyli "wyłuskujemy adres zmiennej x i przypisujemy do wskaźnika wsk.
Takie to zagmatwane, że już się pogubiłem. Nie rozpisywałem się tu o używaniu wskaźników w funkcjach, bo chciałbym najpierw zrozumieć podstawy.
Mój problem polega na tym, że nie wiem czy to dobrze zrozumiałem a już na pewno nie rozumiem po co tak komplikować kod programu i do czego może mi to posłużyć. Może ktoś wytłumaczy mi to bardziej "łopatologicznie" najlepiej na jakimś przykładzie prostego kodu np: miganie LED czy wyświetlanie wyniku na LCD. Byle bym tylko zrozumiał o co w tym wszystkim chodzi. Może na przykładzie prostego kodu to szybciej zrozumiem.
Z góry wszystkim dziękuję i pozdrawiam wszystkich forumowiczów.

_________________
http://www.avrboss.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 7 lut 2020, o 20:47 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 26150
Lokalizacja: Szczecin
Pomógł: 995

mario2015 napisał(a):
Jeżeli chcemy żeby adres wskaźnika wskazywał na adres innej zmiennej, to piszemy tak:
wsk = x;

Tu pierwszy błąd

wsk - to ADRES

a

x - to wartość zmiennej x

a więc trzeba tak

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


czyli wykorzystujesz operator pobierania adresu "&"

------------------------ [ Dodano po: 2 minutach ]

mario2015 napisał(a):
Jeżeli teraz chcemy zmienić wartość tej komórki x to znowu piszemy
*wsk = nowa wartość;


troszkę mieszasz
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


oznacza że pod adres wsk - zapisujesz wartość STAŁEJ DOSŁOWNEJ - 123

a jeśli napiszesz tak

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


to zapiszesz pod adres wsk - wartość zmiennej x

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 7 lut 2020, o 20:52 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 31 mar 2015
Posty: 275
Pomógł: 16

Wskaźnik - coś wskazać! Wskazujesz nazwę. Ty chcesz wskazać co znajduje się w komórce 10 pamięci procesora - można i tak pytać bezpośrednio. W BB rozpocznij powtórkę w rozdziale 3.3.1.3 i przejdź do rozdziału 3.8. Ze wskaźnikami wiąże się operator pobierania adresu. Tak prosto - służą do czytania pamięci. Adres(&) - co tam?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 7 lut 2020, o 20:56 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 26150
Lokalizacja: Szczecin
Pomógł: 995

Wirnick napisał(a):
W BB rozpocznij powtórkę w rozdziale 3.3.1.3 i przejdź do rozdziału 3.8. Ze wskaźnikami wiąże się operator pobierania adresu.

dobra wskazówka ;)

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 16 lut 2020, o 21:55 
Offline
Użytkownik

Dołączył(a): 12 kwi 2017
Posty: 44
Pomógł: 0

Może taki przykład się przyda :

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 16 lut 2020, o 23:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 wrz 2015
Posty: 428
Lokalizacja: Zamość
Pomógł: 13

Obejrzeć też


Wysłane z mojego moto g(6) przy użyciu Tapatalka



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 17 lut 2020, o 10:29 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 06 mar 2015
Posty: 157
Pomógł: 7

anat w twoim kodzie romumiem linie np: 4 i 5, w których deklarujesz wskaźniki typu uint8_t na zmienne on i off.
W linii 12 przypisujesz do zmiennej wskaźnikowej ( do wskaźnika ) zawartość 2-go elementu tablicy tab (przypisanie wartości do wskaźnika).
W 13 linii do zmiennej off przypisujesz to co wyłuskasz z pod adresu gdzie zapisana jest zmienna off1 (chyba) za pomocą operatora wyłuskania &.
W linii 18 wystawiasz na PORTC wartość wskaźnika *on czyli generalnie to co mamy zapisane w tablicy tab[1].
W linii 20 wystawiasz na PORTC wartość wskaźnika off, do którego w linii 13 przypisałeś wartość jaka znajduje się pod adresem gdzie została zapisana zmienna off1.
Pozostałe linijki kodu rozumiem ale te, które opisałem wyżej to tylko mi się wydaje że je rozumiem, no chyba że moje rozumowanie w tym przypadku jest dobre.
Jeśli dobrze to zrozumiałem, to nadal nie rozumiem po co tak komplikować program, skoro są łatwiejsze zapisy kodu, chociażby w linijkach od 23 do 31
chyba że ma to znaczenie nie wiem, może w jakichś funkcjach?

Misiek_86 Poradniki Mirka na temat wskaźników oglądałem po kilka razy ale nadal kicha.

_________________
http://www.avrboss.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 17 lut 2020, o 10:46 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 sty 2016
Posty: 967
Lokalizacja: Kraków
Pomógł: 84

mario2015, nie widzisz sensu w używaniu wskaźników. Przykłady podane przez kolegów są bardzo proste, dlatego wydaje Ci się, że to niepotrzebna komplikacja.
A wyobraź sobie taką sytuację, kiedy w zależności od warunków masz kilka zestawów parametrów. Albo masz program, w którym masz kilka (załóżmy 10) wersji językowych (wytłumaczę na tym drugim przykładzie).
Tworzysz sobie tablicę z językami, np. jezyki[10][50]
Dla każdego języka masz ten sam układ napisów (czyli zerowy element to 'cześć', pierwszy to 'menu', itd.)
Jeżeli chcesz wyświetlić w różnych miejscach programu różne napisy, musisz pamiętać o wstawieniu obydwu współrzędnych. Ale możesz też przypisać do wskaźnika adres pierwszego elementu dla danego języka i wyciągać tylko drugi indeks.
To tylko taki przykład, może pomoże w zrozumieniu. Mam nadzieję, że nie namieszałem za bardzo.
I nie wiem, czy nie pomyliłem kolejności indeksów.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 17 lut 2020, o 11:06 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 06 mar 2015
Posty: 157
Pomógł: 7

Marhef no właśnie nie pojmuję tego.
Cytuj:
Jeżeli chcesz wyświetlić w różnych miejscach programu różne napisy, musisz pamiętać o wstawieniu obydwu współrzędnych. Ale możesz też przypisać do wskaźnika adres pierwszego elementu dla danego języka i wyciągać tylko drugi indeks.

Może napiszesz jakiś fragment kodu do twojego przykładu jak to wykorzystać? Może wtedy mi to trochę coś rozjaśni bo przecież z danej tablicy też mogę sobie wyciągać
dowolny element.

_________________
http://www.avrboss.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 17 lut 2020, o 11:18 
Offline
Użytkownik

Dołączył(a): 12 kwi 2017
Posty: 44
Pomógł: 0

W linii nr 13. wpisywany jest adres zmiennej off1.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 17 lut 2020, o 13:03 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 sty 2016
Posty: 967
Lokalizacja: Kraków
Pomógł: 84

mario2015 napisał(a):
Może napiszesz jakiś fragment kodu do twojego przykładu
Jak złapię chwilę. Ale to nie szybko.
I chyba faktycznie podałem mało miarodajny przykład. Tu faktycznie możesz to na tablicy zrobić.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 17 lut 2020, o 19:47 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 31 mar 2015
Posty: 275
Pomógł: 16

@mario2015 - Wiem, że potrafisz odczytywać i modyfikować zdefiniowaną zmienną(uint8_t w = 35, to w programie głównym piszesz w = 40)
Mam takie pytanie - czy potrafisz zmienić wartość w poprzez wskaźnik?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 18 lut 2020, o 08:17 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 06 mar 2015
Posty: 157
Pomógł: 7

Wirnick , więc myślę, że to będzie tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

_________________
http://www.avrboss.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 18 lut 2020, o 08:57 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 31 mar 2015
Posty: 275
Pomógł: 16

Świetnie! To teraz wykonajmy multiplekser. Np. - mając zadeklarowane/ zdefiniowane osiem zmiennych, zmieniając linie 3 i 4 zmieńmy wartości tych zmiennych. Zauważysz, że za pomocą jednej funkcji możesz odczytywać - modyfikować wiele komórek pamięci procesora przez zmianę adresu i wartości.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 18 lut 2020, o 12:46 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 06 mar 2015
Posty: 157
Pomógł: 7

Wirnick a możesz mnie bardziej nakierować? Jakiego typu funkcji użyć?
np: przekazanie argumentu do funkcji, czy też bez argumentu albo funkcja co zwraca wartość?
I jak to się ma np: 8 różnych zmiennych, 1 funkcja.

_________________
http://www.avrboss.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 18 lut 2020, o 13:34 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 31 mar 2015
Posty: 275
Pomógł: 16

Odczytywanie czterech zmiennych zawarte jest w sterowaniu wyświetlacza LED, ale chodzi o zrozumienie zagadnienia. Zróbmy to na piechotę, a powtarzające się wyrażenia później ubierze się w funkcję jak radzi Mirek. Obecnie siedzę w książkach, ale też włączę zestaw do testowania.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 18 lut 2020, o 14:20 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 06 mar 2015
Posty: 157
Pomógł: 7

A więc tak:
Chcę na wyświetlaczu wyświetlić liczbę 5478.
Tworzę więc zmienne a,b,c i d dla poszczególnych wyświetlaczy (1,2,3,4).
Teraz:
1. Włączam wyświetlacz nr.1 , wysyłam zmienną a i wyłączam ten wyświetlacz.
2. Włączam wyświetlacz nr.2 , wysyłam zmienną b i wyłączam ten wyświetlacz.
3. Włączam wyświetlacz nr.3 , wysyłam zmienną c i wyłączam ten wyświetlacz.
4. Włączam wyświetlacz nr.4 , wysyłam zmienną d i wyłączam ten wyświetlacz.
I tak w kółko.
OK ale jak to się ma do wskaźników?

_________________
http://www.avrboss.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 18 lut 2020, o 14:51 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 31 mar 2015
Posty: 275
Pomógł: 16

Wybrałem zły przykład, chociaż występuje symbol pobierania adresu(&). Zapis &cyfry[cyx] ma związek ze wskaźnikiem i może być 3 linią w kodzie 5 postów wyżej.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 18 lut 2020, o 20:05 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 546
Pomógł: 137

mario2015 napisał(a):
Jeśli dobrze to zrozumiałem, to nadal nie rozumiem po co tak komplikować program, skoro są łatwiejsze zapisy kodu, chociażby w linijkach od 23 do 31
chyba że ma to znaczenie nie wiem, może w jakichś funkcjach?

Rozumiem, że pytasz o sens stosowania wskaźników?

    Wyobraź sobie zdefiniowanie tablicy zawierającej nazwy elementów menu (dla uproszczenia dwie):
  • "Ustawienia transmisji"
  • "PWM"
Można przy użyciu tablicy wielowymiarowej, ale wtedy musisz zadeklarować jeden z jej wymiarów na wartość 22, ponieważ taka jest długość najdłuższej nazwy:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Stosując wskaźniki można zrobić tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

zyskując 14 bajtów (przy większej ilości nazw o zróżnicowanych długościach ten zysk może być dużo większy).

Inna sytuacja, przekazywanie zmiennej do funkcji poprzez wskaźnik:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Może to być np. przydatne, jeśli w jednym z modułów programu mamy zdefiniowaną zmienną lokalną, niewidoczną i niedostępną w innych modułach, ale w jakichś szczególnych okolicznościach chcemy ją udostępnić dla innego modułu. Można to właśnie zrobić, przekazując do innego modułu wskaźnik do tej zmiennej jako argument funkcji.

Można też np. za pomocą argumentu funkcji przekazać z jednego modułu do innego modułu adres bufora (tablicy), do którego ten drugi ma przekopiować dane (np. odebrane wcześniej przez UART).

Wskaźniki mogą być także bardzo przydatne, jeśli przykładowo chcemy do funkcji przekazać jako argument adres jakiegoś portu (lub innego rejestru IO):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


To oczywiście bardzo proste przykłady i może się wydawać, że nie mają większego sensu, ale naprawdę mogą okazać się bardzo przydatne, szczególnie w większych projektach podzielonych na moduły. Można wtedy na przykład za pomocą wskaźników ograniczyć lub zlikwidować konieczność używania zmiennych globalnych widocznych w całym projekcie (stosowanie takich zmiennych jest raczej złą praktyką).

No i oczywiście jednym z podstawowych sposobów wykorzystania wskaźników, o czym pisali już koledzy wcześniej), jest alternatywny (w stosunku do indeksowania) dostęp do elementów tablicy. W tej chwili wydaje Ci się to może trochę mniej czytelne rozwiązanie (nazwałeś to komplikowaniem), ale kiedy dobrze opanujesz temat, to może zmienisz zdanie. Przykładowo funkcja wyświetlająca ciąg znaków (stosując wskaźniki) wyglądałaby jakoś tak (zakładamy, że lcd_putc() wyświetla pojedynczy znak):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Jak wyglądałaby Twoja z odczytem za pomocą indeksu tablicy?

Wskaźniki są też stosowane przez funkcje z biblioteki standardowej, takie jak np. memcpy(), gdzie jako argumenty podajesz wskaźnik do źródła, wskaźnik do celu i rozmiar. Dzięki wskaźnikom (tutaj jest to specjalny typ wskaźnika - void *) funkcja ta może kopiować zmienne praktycznie dowolnego typu, nie tylko tablice, ale też int, float, double, char czy też różne struktury (zawierające elementy różnych typów). Bez wskaźników stworzenie takiej uniwersalnej funkcji byłoby praktycznie niemożliwe.

Nie piszę tu o dynamicznej alokacji pamięci, choć to jeden z podstawowych sposobów użycia wskaźników, ponieważ biorąc pod uwagę stosunkowo małe zasoby pamięci RAM w mikrokontrolerach AVR przy jednoczesnym braku MMU, jej nieumiejętne użycie może dać więcej szkody niż pożytku. Dynamiczna alokacja pamięci powinna być używana ze świadomością ewentualnych konsekwencji i ostrożnie, dlatego nie polecam jej mniej zaawansowanym programistom (przynajmniej na początku poznawania wskaźników).

Trudno tak na poczekaniu wymyślić jakiś stosunkowo prosty i jednocześnie sensowny przykład użycia wskaźników, dlatego skupiłem się na pokazaniu różnic pomiędzy dostępem do zmiennej poprzez wskaźnik a dostępem bezpośrednim. Znając różnice, może sam znajdziesz zastosowanie.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 19 lut 2020, o 15:21 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 06 mar 2015
Posty: 157
Pomógł: 7

andrews - Przeanalizowałem przykłady z Twojego postu i powiem tak:

Przykład 1 z tablicami jakoś nie chce do mnie przemówić, ponieważ nie za bardzo rozumiem w czym mają mi pomóc wskaźniki w tablicach, chyba, że rozchodzi się o wykorzystanie pamięci flash.
Przykład 2 chyba rozumiem. Chodzi chyba o to, że wskaźnikiem możemy zmienić wartość zmiennej przekazanej do funkcji, a bez wskaźnika nie jest to możliwe.
Przykład 3 z wpisywaniem wartości do rejestru to chyba jest coś podobnego do przykładu 2-go ale nie rozumiem jak to działa.
No i przykład 4 to chyba zrozumiałem. Chodzi tu o to, że bez wskaźnika char *c, 2-ga linijka w funkcji po prostu nie zadziała.

Uff, mam nadzieję, że kiedyś te wskaźniki ogarnę.

_________________
http://www.avrboss.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 19 lut 2020, o 20:03 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 546
Pomógł: 137

mario2015 napisał(a):
Przykład 1 z tablicami jakoś nie chce do mnie przemówić, ponieważ nie za bardzo rozumiem w czym mają mi pomóc wskaźniki w tablicach, chyba, że rozchodzi się o wykorzystanie pamięci flash.

Chodziło mi ogólnie o oszczędność pamięci, niekoniecznie musi być to FLASH. Użyłem pamięci FLASH tylko dlatego, że ten sposób zadziała prawidłowo tylko przy tablicach const, a w AVR szkoda RAM na dane const, lepiej je zapisywać we FLASH.

Stosując tablicę dwuwymiarową musisz ustawić jeden z wymiarów na wartość równą długości najdłuższego z ciągów. Jeśli masz do zapisania jeden ciąg o długości 22 bajty i np. pięć ciągów o długości 5 bajtów to suma wyniesie 47 bajtów, a tablica musi mieć rozmiar 6 * 22 bajty = 132 bajty. Używając wskaźników, tak jak pokazałem, użyjesz tylko 47 bajtów + 6 razy po 2 bajty (na wskaźniki), czyli 59 bajtów.


Przykład 2 OK.

Przykład 3 Ogólnie zrozumiałeś dobrze, a działa to dlatego, że tak naprawdę nazwy portów czyli te wszystkie PORTA, PORTB, DDRA a nawet TCCR1A, UCSR1B to tak naprawdę wskaźniki, nie wartości. Więcej szczegółów można znaleźć w plikach sfr_defs.h i plikach ioxxx.h (gdzie xxx to kod typu uC), ale dla Ciebie to chyba jednak jeszcze za wcześnie.

Przykład 4 Tutaj chciałem pokazać zwięzłość zapisu przy użyciu wskaźników (a propos Twojej wypowiedzi o "komplikowaniu" kodu poprzez użycie wskaźników). Gdyby w tej samej funkcji użyć indeksów tablicy:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

To bardzo prosta funkcja, ale już widać różnicę (niewielką, ale jednak), choćby w konieczności zdefiniowania dodatkowej zmiennej pomocniczej, no i zapis jest też nieco dłuższy. Najprawdopodobniej też kod wygenerowany przy użyciu wskaźników będzie bardziej optymalny (zajmie mniej miejsca w pamięci FLASH i będzie wykonywany nieco szybciej).

Należy też pamiętać o tym, że tablice są przekazywane do funkcji tylko poprzez wskaźnik (nigdy nie jest tworzona kopia zmiennej tablicowej w całości przekazywana do funkcji, chyba że tablica jest elementem struktury). Jest to ważne o tyle, że w tej sytuacji funkcja może nie tylko odczytywać z tablicy, ale też zapisywać do niej. Nie zawsze to jest pożądane, więc aby uniknąć niezamierzonej modyfikacji tablicy, powinniśmy ją przekazać w trybie "tylko do odczytu":
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Przekazując tablicę (a właściwie wskaźnik na nią) tab do funkcji func_read_only() mamy pewność, że nie zmieni ona zawartości tablicy.


Starałem się, żeby przykłady były stosunkowo proste i obrazowały różnicę pomiędzy dostępem bezpośrednim i poprzez wskaźnik. Próbowałem też podać przykłady, kiedy korzystne lub nawet konieczne jest użycie wskaźników. Wydaje mi się jednak, że na początku nauki o wskaźnikach należy po prostu uwierzyć, że mogą być bardzo pomocne, zacząć od prostych rzeczy, nie zniechęcać się, a w miarę postępów w nauce sens i korzyści użycia wskaźników będą stawały się oczywiste.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 20 lut 2020, o 08:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 31 mar 2015
Posty: 275
Pomógł: 16

Ja wspomnę o zasadzie matematyki, którą trzeba mieć zawsze na uwadze stosując wskaźniki. Dwie zmienne obok siebie wyrażają mnożenie. Np. Pole prostokąta = a * b = ab. Tak samo jest w programowaniu - wyświetl(w); // jest równoważne z wyświetl *w;. Nie wiem czy kompilator mi na to pozwoli sprawdzając pisownię, lecz wyświetlona zostanie wartość z adresu ukrytym w nazwie zmiennej w. Podobnie jest z tablicami - wyświetl(*tab); //wyświetli się wartość pierwszego elementu tablicy. To samo wyświetlone zostanie wyrażeniem wyświetl(tab) z pominięciem znaku wyłuskiwania(*). Natomiast wyświetl(&tab); wyświetli nam wartość adresu pierwszego elementu ukrytego w nazwie tab. Nazwa "tab" już jest wskaźnikiem(drogowskazem na ... ).



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 20 lut 2020, o 10:24 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 546
Pomógł: 137

Wirnick napisał(a):
wyświetl(w); // jest równoważne z wyświetl *w;

Jeśli chciałeś porównać dwa różne wywołania tej samej funkcji, to w drugim wywołaniu brakuje Ci nawiasu: wyświetl(*w);

I nie, w takim przypadku wywołania wyświetl(w); oraz wyświetl(*w); wcale nie są równoważne. Nie możesz sobie zwyczajnie pominąć operatora dereferencji i oczekiwać, że rezultat będzie taki sam. Tak samo zresztą podczas programowania nie możesz pominąć operatora mnożenia wynik = ab;, ponieważ "ab" zostanie potraktowane jako inna zmienna, a nie jako mnożenie zmiennych "a" i "b".



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 20 lut 2020, o 10:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 31 mar 2015
Posty: 275
Pomógł: 16

andrews napisał(a):
I nie, w takim przypadku wywołania wyświetl(w); oraz wyświetl(*w); wcale nie są równoważne.

Tak myślałem, że popełniłem błąd. Wydaje mi się,że zapis wyświetl(*w) w pełnej interpretacji matematycznej wyglądał by wyświetl*(*w) - co jest czymś innym. Na pewno wszystkiego nie wiem.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
 Tytuł: Re: Wskaźniki
PostNapisane: 20 lut 2020, o 13:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 06 mar 2015
Posty: 157
Pomógł: 7

andrews dzięki za cenne uwagi. Teraz nie zostało mi nic innego jak wykorzystać twoje rady jak i rady kolegów, którzy udzielili mi odpowiedzi i po części nakierowali na właściwy trop.
Wszystkim jeszcze raz dziękuję.
A teraz będą długie wieczory spędzone ze wskaźnikami.
Myślę, że po waszych wypowiedziach będzie mi teraz łatwiej to zrozumieć.
Jeszcze raz wszystkim dziękuję.

_________________
http://www.avrboss.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 25 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO