Skocz do zawartości

Tablice w Arduino – #2 – organizacja pamięci


Gieneq

Pomocna odpowiedź

Kolejna część kursu, tym razem postanowiłem zagłębić się w temat pamięci SRAM. Myślę, że w tym temacie można jeszcze sporo napisać, ale ten stopień szczegółowości powinien umożliwić nabudowanie świadomości jak te 2 KiB pamięci są używane, co się właściwie dzieje ze zmiennymi, do czego jest specyfikator static.

  • Lubię! 1
Link do komentarza
Share on other sites

Też dobry odcinek, muszę jeszcze raz przeczytać.

Dalej nie wiem po kiego grzyba te wskaźniki są potrzebne, aż poczytałem jeszcze to ale dalej nie kapuję na co mi znać adres w pamięci jakiejś zmiennej. Po co się do niej do niej odwoływać przez wskaźnik, a nie bezpośrednio. 

Dlaczego mam pytać Piotrka co Krzysiu ma w kieszeni skoro Krzysiu stoi tuż obok i mogę jego zapytać.

 

Edytowano przez SOYER
Link do komentarza
Share on other sites

27 minut temu, SOYER napisał:

na co mi znać adres w pamięci jakiejś zmiennej.

int divide(int a, int b, int *remainder)
{
  if (remainder) *remainder = a % b;
  return a/b;
}

// i gdzieś w kodzie

int wynik1, wynik2, reszta1, reszta2;

wynik1=divide(dzielna1, dzielnik1, &reszta1);
wynik2=divide(dzielna2, dzielnik2, &reszta2);


  

Na przykład po to.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

40 minut temu, SOYER napisał:

Dalej nie wiem po kiego grzyba te wskaźniki są potrzebne, aż poczytałem jeszcze to ale dalej nie kapuję na co mi znać adres w pamięci jakiejś zmiennej.

Ja rzadko uzywam, ale juz widze ze wskaznik to takie cos co bardzo potrafi zycie uproscic😉 

Np. kopiujesz blok pamieci do innego bloku, ale chcesz tylko przekopiowac polowe...i jak to zrobic? Albo kombinowac z for, albo uzyc wskaznika i przesunac sie na odpowiedni adres...kilka szlaczkow i gotowe😉

44 minuty temu, SOYER napisał:

Po co się do niej do niej odwoływać przez wskaźnik, a nie bezpośrednio. 

A co jesli masz np. 5 zmiennych static w funkcji, i z tej funkcji wchodzisz w inna funkcje w ktorej chcesz zmienic wartosci tych powyzej? Zmienne nie sa juz widziane  globalnie, wiec bez wskaznika juz nie dobierzesz sie do oryginalow..😉 (mozna referencje, ale wskaznik daje znacznie wiecej mozliwosci)

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Jako inny przyklad...to masz 10 roznych struktur, ale chcesz wszystkie wysylac poprzez jedna funkcje...to mozesz sobie stworzyc uniwersalna funkcje gdzie pierwszy argument to wskaznik na adres konkretnej struktury(rzutowany na bajt np) a drugi to rozmiar konkretnej struktury...(mozna tez chyba ze wskaznikiem typu void kombinowac, ale ja sie nie znam)...bardzo duzo funkcji bibliotecznych dziala tylko na wskaznikach/adresach...tak ze w zaawansowanym programowaniu(ktorego nigdy nie doswiadcze😢) bez powyzszego ni hu hu...😉 

Link do komentarza
Share on other sites

58 minut temu, ethanak napisał:

int divide(int a, int b, int *remainder)
{
  if (remainder) *remainder = a % b;
  return a/b;
}

// i gdzieś w kodzie

int wynik1, wynik2, reszta1, reszta2;

wynik1=divide(dzielna1, dzielnik1, &reszta1);
wynik2=divide(dzielna2, dzielnik2, &reszta2);


  

Na przykład po to.

Nie łapię,

robimy funkcję z 3 argumentami, tym trzecim jest wskaźnik(czyli adres) zmiennej reminder 

w ciele tej funkcji sprawdzamy czy zawartość zmiennej reminder jest różna od zera, jeśli tak to resztę z dzielenia zapisujemy jako wskaźnik do zmiennej reminder(czyli ta reszta jest od teraz adresem tej zmiennej) 

i teraz co to ma wspólnego z tym:

wynik1=divide(dzielna1, dzielnik1, &reszta1);

do zmiennej wynik1 zapisujemy to co zwraca funkcja divide(a zwraca int-a z dzielenia a/b), jednak do tej funkcji przekazujemy, a, b i ??adres zmiennej reszta1??

Dobrze przeczytałem kod?

Jednak nie widzę nadal zależności, co i po co?

 

Link do komentarza
Share on other sites

Zwracasz wynik dzielenia tradycyjnie retur'nem i jednoczesnie reszte z dzielenia poprzez wskaznik...

Nie adresem...uzycie gwiazdki wyluskuje wartosc spod tego wskaznika a nie adres...gdyby nie bylo gwiazdki to twoja reszta byla by nowym adresem😜...ogolnie katastrofalne skutki

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

@SOYER Żle.

Porównaj:
 

wynik1 = divide(dzielna1, dzielnik1, &reszta1);

wynik2 = divide(dzielna2, dzielnik2, NULL);

 

10 minut temu, SOYER napisał:

w ciele tej funkcji sprawdzamy czy zawartość zmiennej reminder jest różna od zera

Nie. Sprawdzamy, czy wskaźnik jest różny od zera, i jeśli tak to pod wskazany adres wstawiamy resztę.

Edytowano przez ethanak
Link do komentarza
Share on other sites

void fun1() {
  static byte q = 9;
  fun2(&q);            //pobiera adres
}

void fun2(byte * s) {  //tworzy wskaznik i przypisuje adres "q"
*s++;                  // zwieksza zawartosc "q" o 1
}

takie proste cos np. pokazuje ze wskaznik sie przydaje...wyobraz sobie ze masz 10 takich zmiennych, albo strukture, ktore musza byc statyczne w funkcji z jakichs powodow...wtedy juz bylby problem bez wskaznika..

Link do komentarza
Share on other sites

@ethanakZałapałem z tego szkicu tyle, że *reminder jest wskaźnikiem do zmiennych( reszta1, reszta2) zależnie od tego co liczymy. 

Wynik to int z dzielenia, a resztę z tego dzielenia przechowujemy w kolejnej zmiennej. 

Więc ten przykład na to jak to zrobić by zmienne reszta nie były globalne, czy inaczej?

Link do komentarza
Share on other sites

18 minut temu, SOYER napisał:

@ethanak 

 

Więc ten przykład na to jak to zrobić by zmienne reszta nie były globalne, czy inaczej?

Nie nie...chodzi o to ze wchodzac do funkcji nie wiesz ktora zmienna zostala podana jako argument...czy reszta1/reszta2...wiec uzywasz wskaznika zeby bylo prosto i szybko, bo return'a uzyc nie mozesz bo zostal juz zarezerwowany dla wynik1/2

Wracajac do bibliotek to zwroc uwage ze czesto jako argumenty podajesz "&zmienna"...dlaczego? Bo inaczej w funkcjach zrobil bys kopie i na nich operowal a czesto chodzi o operacje na oryginalach wiec musisz uzyc wskaznika...

Edytowano przez farmaceuta
  • Pomogłeś! 1
Link do komentarza
Share on other sites

23 minuty temu, farmaceuta napisał:

nie...chodzi o to ze wchodzac do funkcji nie wiesz ktora zmienna zostala podana jako argument...czy reszta1/reszta2...wiec uzywasz wskaznika zeby bylo prosto i szybko,

Ok, załapałem, dzięki. Teraz to logiczne, przykład ethanaka jak zwykle hydrozagadka na początku, teraz widzę jakie to banalne. Faktycznie może to upraszczać pisanie. Ja dotychczas takich rzeczy nie miałem potrzeby używać, albo nie wiedziałem, że tak można;).

ethanak, farmaceuta 🍻🍻

  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.