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



Teraz jest 28 mar 2024, o 21:26


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 12 ] 
Autor Wiadomość
PostNapisane: 6 maja 2020, o 12:01 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Witam .

Mam problem ze zrozumieniem do końca działania funkcji z przykładu z żółtej książki..

W pewnym przykładzie jest tak:

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

Rozumiem że buf to jest zmienna tekstowa a jej rozmiar określa UART_RX_BUF_SIZE w podanym przypadku zawsze wynosi 256

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

Rozumem że w/w funkcja przyjmuje argument buf - natomiast funkcja nie zwraca wyniku - czy tak?

Funkcja w swojej definicji wygląda tak - (przepraszam jeśli nie mogę udostępniać to przepraszam i zaraz zapis skasuję) :

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


I proszę mi podpowiedzieć co się dzieje dalej i do tego momentu rozumuję to tak : argument czyli zmienna buf wpada do zmiennej rbuf i tu nie rozumem co robi ten wskaznik * w funkcji:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Pytam o to bo nie mogę do końca zrozumieć czym jest ten wskażnik i jak mam go sobie wyobrazić ??



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 maja 2020, o 16:21 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 28 kwi 2015
Posty: 20
Lokalizacja: Bydgoszcz
Pomógł: 0

Według mnie:
char buf[UART_RX_BUF_SIZE] jest tablicą.
W wywołaniu funkcji UART_RX_STR_EVENT( buf ) buf jest wskaźnikiem do tej tablicy wskazujący pierwszy jej element.
Dlatego w definicji funkcji void UART_RX_STR_EVENT(char * rbuf) {...} jest wskaźnik.
Dlaczego rbuf a nie buf tego nie wiem. Choć podejrzewam, że to bez znaczenia.
Funkcja nie zwraca wyniku bo dokonuje (dzięki wskaźnikowi) zmian bezpośrednio w tablicy char buf[UART_RX_BUF_SIZE].
Choć mogę się mylić.
Warto poczytać o argumentach do funkcji w C/C++ Link



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 maja 2020, o 16:33 
Offline
Użytkownik

Dołączył(a): 11 sty 2015
Posty: 166
Pomógł: 24

Masz Mirka książki. Musisz trochę doczytać o tych wskaźnikach, bo ciężko to będzie wytłumaczyć w kilku zdaniach, ale spróbuję.
Tablica buf jak napisałeś ma rozmiar 256 znaków.
Teraz wyobraź sobie że przekazujesz tą tablicę do funkcji, (tak jak zwykłą zmienną). Tablica ta musiała by być wówczas skopiowana na stosie. Łatwo ten stos przepełnić i program idzie " w las".
Dlatego do funkcji nie jest przekazywana cała tablica 256 bajtów tylko sam wskaźnik, czyli adres tej tablicy o długości 2 bajtów. I to wszystko.
Stąd w definicji funkcji masz właśnie jako parametr wskaźnik (adres).
W samym wywołaniu funkcji jest już sam buf, bo kompilator domyślnie przy tablicy traktuje buf jako wskaźnik (adres na tablicę) a nie same dane w tablicy.
Ale możesz również napisać &buf i wtedy jednoznacznie widać że chodzi o adres, a działać będzie tak samo.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 maja 2020, o 16:38 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 lut 2017
Posty: 369
Lokalizacja: Gliwice
Pomógł: 34

auers napisał(a):
Ale możesz również napisać &buf i wtedy jednoznacznie widać że chodzi o adres, a działać będzie tak samo.

No tak to nie, poprawnie to &buf[0].



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 maja 2020, o 16:39 
Offline
Użytkownik

Dołączył(a): 11 sty 2015
Posty: 166
Pomógł: 24

karlowic napisał(a):
Dlaczego rbuf a nie buf tego nie wiem. Choć podejrzewam, że to bez znaczenia.

Nie bez znaczenia tylko w definicji funkcji jako argument jest rbuf, dlatego lokalnie w funkcji używa się właśnie tej nazwy..
Sam buf natomiast to zmienna globalna.
karlowic napisał(a):
Funkcja nie zwraca wyniku bo dokonuje (dzięki wskaźnikowi) zmian bezpośrednio w tablicy char buf[UART_RX_BUF_SIZE].
Choć mogę się mylić.

Nie mylisz się, dokłanie tak jest.

------------------------ [ Dodano po: 6 minutach ]

Zealota napisał(a):
auers napisał(a):
Ale możesz również napisać &buf i wtedy jednoznacznie widać że chodzi o adres, a działać będzie tak samo.

No tak to nie, poprawnie to &buf[0].

Tak masz rację, ewentualnie z rzutowaniem czyli (char*) &buf.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 maja 2020, o 20:58 
Offline
Użytkownik

Dołączył(a): 07 lut 2015
Posty: 156
Pomógł: 2

Uważam, że dobrze gdy są tak fundamentalne pytania i kompetentne odpowiedzi.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 maja 2020, o 08:45 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

No tak kolega karlowic napisał : W wywołaniu funkcji UART_RX_STR_EVENT( buf ) buf jest wskaźnikiem do tej tablicy wskazujący pierwszy jej element , ale ja tu nie mogę czegoś zrozumieć:
buf to jest tablica - czy tak? mająca do 256 znaków w rozumieniu pojęcia wskaznika mamy do czynienia wskazanie na komórkę pamięci - jaką czy w rozumieniu UART_RX_STR_EVENT( buf )
czyli wkaznik wskazać może na funkcje i kolejny nie zrozumialy fakt? jak buf będzie miał w sobie np. 256 zapełnionych znaków w tablicy to który konkretnie znak tej tablicy wskaże w/w komórkę
pamięci odpowiadającej wskażnikowi do w/w funkcji?
Przepraszam ja może żle zrozumiałem istotę tematu proszę mnie poprawić jeśli coś zle rozumuję?

------------------------ [ Dodano po: 5 minutach ]

AKSELINEK napisał(a):
No tak kolega karlowic napisał : W wywołaniu funkcji UART_RX_STR_EVENT( buf ) buf jest wskaźnikiem do tej tablicy wskazujący pierwszy jej element , ale ja tu nie mogę czegoś zrozumieć:
buf to jest tablica - czy tak? mająca do 256 znaków w rozumieniu pojęcia wskaznika mamy do czynienia wskazanie na komórkę pamięci - jaką czy w rozumieniu UART_RX_STR_EVENT( buf )
czyli wkaznik wskazać może na funkcje i kolejny nie zrozumialy fakt? jak buf będzie miał w sobie np. 256 zapełnionych znaków w tablicy to który konkretnie znak tej tablicy wskaże w/w komórkę
pamięci odpowiadającej wskażnikowi do w/w funkcji?
Przepraszam ja może żle zrozumiałem istotę tematu proszę mnie poprawić jeśli coś zle rozumuję?




Teraz wyobraź sobie że przekazujesz tą tablicę do funkcji, (tak jak zwykłą zmienną). Tablica ta musiała by być wówczas skopiowana na stosie. Łatwo ten stos przepełnić i program idzie " w las".
Dlatego do funkcji nie jest przekazywana cała tablica 256 bajtów tylko sam wskaźnik, czyli adres tej tablicy o długości 2 bajtów. I to wszystko.
Stąd w definicji funkcji masz właśnie jako parametr wskaźnik (adres).

To jak buf będzie miał np 256 znaków to który znak wskaże konkretna pamięc w rozumowaniu wskaznika funkci

Jeszcze raz uproszczę rozumowanie b o namieszałem...
Ja rozumuje w ten sposób być może złe - funkcja UART_RX_STR_EVENT( buf ) jako jakiś element pamięci gdześ się znajduje , a to gzie dokładnie określa wskażnik buf czy tak?
adres tej pamięci jest dwubajtowy i przekazuje go buf ale buf moze mieć 256 znaków to które konkretnie znaki buf to przekazują buf[0] i buf[1] czy jakieś inne?

i jeszcze jedno niezrozumiałe dla mnie : to jak to jest raz buf jest tablicą a raz zmienną globalną ??



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 maja 2020, o 09:09 
Offline
Użytkownik

Dołączył(a): 24 sty 2012
Posty: 1469
Pomógł: 56

Niepotrzebnie mieszasz sobie dwie rzeczy.
Funkcję i wskaźnik.
Wskaźniki to takie narzędzia, które pokazują miejsca w pamięci.
W tym przypadku funkcja otrzymuje parametr. Parametry przy funkcjach są po to by móc wykonywać funkcje z różnymi zestawami danych.
Tu jako parametr musimy funkcji dostarczyć wskaźnik na obszar pamięci w którym będzie ona zapisywała odebrane z UARTa dane.
Wskaźnik to taki specjalny rodzaj zmiennej który przechowuje adres. Wskaźniki mogą być różnych typów a w tym przypadku jest to char.
Jeśli wywołasz tą funkcję jak pokazałeś:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

to niezależnie od tego co znajduje się w tablicy buf wskaźnik pokaże na pierwszy jej element.

_________________
Jestem początkujący i moje porady mogą być błędne



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 maja 2020, o 11:46 
Offline
Użytkownik

Dołączył(a): 11 sty 2015
Posty: 166
Pomógł: 24

AKSELINEK napisał(a):
Jeszcze raz uproszczę rozumowanie b o namieszałem...
Ja rozumuje w ten sposób być może złe - funkcja UART_RX_STR_EVENT( buf ) jako jakiś element pamięci gdześ się znajduje , a to gzie dokładnie określa wskażnik buf czy tak?

Tak jak kolega MirkoT napisał, niepotrzebnie sobie komplikujesz.
Funkcja to funkcja, fragment programu który działa na danych które przekazujesz przez parametry w nawiasie.
W tym przypadku funkcja UART_RX_STR_EVENT operuje na danych z tablicy buf, a te dane są podane przez wskazanie adresu w pamięci gdzie się znajdują.
Cytuj:
adres tej pamięci jest dwubajtowy i przekazuje go buf ale buf moze mieć 256 znaków to które konkretnie znaki buf to przekazują buf[0] i buf[1] czy jakieś inne?
Wskaźnik pokazuje na pierwszy element tablicy, ale nic nie stoi na przeszkodzie aby się odwołć do innego elementu.
Jak przejrzysz sobie np. funkcje do wyświetlania stringów na wyświetlaczu LCD lub przez uart to masz tam często coś takiego (*wks++).
Czyli do funkcji podajesz wskaźnik na pierwszy znak w tablicy, a później w funkcji zwiększasz ten adres (wsk++) czyli wyświetlasz kolejne znaki. I tak do końca stringu, czyli w C dopóki nie pobierzesz z tablicy wartości 0.
Cytuj:
i jeszcze jedno niezrozumiałe dla mnie : to jak to jest raz buf jest tablicą a raz zmienną globalną ??
Jedno nie przeszkadza drugiemu. buf jest tablicą, a zmienna globalna oznacza tyle, że jest widziana w programie głównym. Takich zmiennych możesz mieć kilka np buf_Tx, buf_RX, czyli: np bufor nadawczy lub bufor odbiorczy. Możesz sobie dać dowolną nazwę. Pisząc funkcję np. w bilbliotece nie musisz wiedzieć jaka nazwę zmiennej globalnej nada użytkownik biblioteki. W argumencie funkcji nadajesz sobie dowolną nazwę i nią operujesz pisząc ciało funkcji. Później do tej funkcji przekazujesz zmienną globalną. Dlatego jedną funkcją zdefiniowaną print_string(char* buf), Możesz wyświetlić na LCD bufor o dowolnej nazwie np. buf_Tx przez wywołanie print_string(buf_Tx), lub print_string(buf_Rx), albo jeszcze inny string/tablica o jeszcze innej dowolnej nazwie.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 maja 2020, o 15:28 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Dzięki chyba trochę mi się rozjaśniło - czyli funkcja nieważne gdzie się znajduje w pamięci ważne że dane które są jej dostarczane wpadają na określony dla jej zakresu danych adres za pomocą wskażnika i początek danych wskażnika zawsze wpadnie na pierwszy element zestawu danych potrzebnych do działania funkcji?
Czy tak to jest??



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 maja 2020, o 15:49 
Offline
Użytkownik

Dołączył(a): 11 sty 2015
Posty: 166
Pomógł: 24

AKSELINEK napisał(a):
Dzięki chyba trochę mi się rozjaśniło - czyli funkcja nieważne gdzie się znajduje w pamięci ważne że dane które są jej dostarczane wpadają na określony dla jej zakresu danych adres za pomocą wskażnika i początek danych wskażnika zawsze wpadnie na pierwszy element zestawu danych potrzebnych do działania funkcji?
Czy tak to jest??
Nie bardzo wiem, co rozumiesz przez to, że dane wpadają na określony za pomocą wskaźnika adres.
Dane są w konkretnym miejscu w pamięci. Przydzielona jest im konkretna ilość pomięci którą określa wielkość tablicy.
Teraz do funkcji przekazany jest adres tej pamięci.
I w zależności od tego co jest w funkcji, albo te dane są odczytywane, albo pod tym adresem dane są zapisywane.
W tym przypadku w funkcji UART_RX_STR_EVENT, najpierw funkcja uart_get_str odczytuje dane z UART'u i zapisuje pod wskazanym adresem.
Następnie te same dane są przekazane również przez wskaźnik do kolejnej funkcji uart_rx_str_event_callbac.
W ten sposób dane są w jednym miejscu a kolejne funkcje korzystają z tych samych danych.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 maja 2020, o 17:25 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2017
Posty: 546
Pomógł: 0

Dzięki to teraz już mi się więcej rozjaśniło dzięki



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: 12 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 10 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