Skocz do zawartości

[C] Parametry funkcji ?


MasterFun

Pomocna odpowiedź

Witam!

Czy mógłby mi ktoś wytłumaczyć na tzw. chłopski rozum o co chodzi z parametrami (argumentami) jakie przyjmuje funkcja, otóż w diodowym kursie C jest o tym mowa podczas inicjowania sygnałów dla buzzera mianowicie chodzi mi o ten fragment

void beep(unsigned int frequency, unsigned int duration)

Z innych kursów wnioskuję że funkcja pobiera argumenty frequency i duration, ale gdzie pobiera, po co. Dowiedziałem się również że należy traktować to jak zwykłe zmienne w funkcji z tym że mają one przypisaną wartość podczas wywoływania funkcji, ale co to znaczy? W przykładzie z buzzerem traktować tego jako zwykłą zmienną nie można, bo buzzer nie działa - sprawdzałem i to...

Przeczytałem kurs diodowy, inny kurs na stronie o programowaniu w C oraz rozdział w książce "szkoła programowania język C" S.Prata

Ale jakoś nie dociera to do mnie, tzn. w każdym wypadku jest to opisane tak samo, jeśli byłaby możliwość prosiłbym również o jakiś przykład. No i ew. coś w formie mini algorytmu pokazującego w jaki sposób ma działać ten buzzer.

Moja wiedza o funkcjach - wiem co to jest, do czego służy, po zrobieniu wszystkiego co jest w niej wpisane może zwracać jakąś wartość którą później można wykorzystać w np. jakiejś zmiennej (w zależności co jest wpisane na początku - to zwraca).

Link do komentarza
Share on other sites

jak masz takie coś:

void beep(unsigned int frequency, unsigned int duration)

to gdy wywołasz funkcję w swoim programie, z argumentami np 10 i 20:

beep(10, 20);

To w samej funkcji, w każdym miejscu, gdzie masz użytą zmienną frequency będziesz miał wartość za nią podstawioną 10, a wszędzie gdzie użyjesz zmiennej duration będziesz miał podstawioną wartość 20. A po co pobiera? To by trzeba ogarnąć cały kod tejże funkcji, co robi z tymi zmiennymi frequency i duration.

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

Są trzy główne przypadki:

a) Dane przekazane do funkcji jako zwykłe zmienne są w funkcji danymi lokalnymi i GINĄ razem z końcem funkcji.

pseudokod:

void main()

{

char a=5;

f(a);

printf(a);

}

f(char a)

{

a=a+5;

printf(a);

}

a w funkcji main będzie stale 5, mimo, że lokalne a w funkcji f uzyska wartość 10, ale ta zmienna zginie razem z końcem funkcji.

W praktyce to wygląda tak, że przed wywołaniem funkcji f na stos (lub do rejestru) procesor wrzuci wartość 5 i skoczy do kodu funkcji f. Tam rejestr zwiększy o 5 (a=a+5) a następnie zrobi powrót z funkcji i wyrzuci informacje zapisane w tym rejestrze w kosmos.

W praktyce dobry kompilator powinien zoptymalizować kod i to a=a+5 nigdy by się nie wywołało, bo kompilator wie, że wynik nigdzie nie będzie użyty.

b) Do funkcji możesz przekazać wskaźnik do pamięci gdzie są jakieś dane. Wskaźnik zginie z końcem funkcji, ale jak zmienisz dane w pamięci (na które wskazuje wskaźnik) to oczywiście one w pamięci zostają zmienione i reszta programu będzie te zmiany widziała.

c) Możesz używać danych globalnych, do których dostęp jest z każdego miejsca w kodzie. Taka dana zmieniona w funkcji będzie nadal zmieniona poza nią.

Tutaj jest jedna ważna rzecz dla mikrokontrolerów. Z powodów optymalizacji procesor pobiera jakąś daną z pamięci do rejestru, tak wykonuje wszystkie potrzebne operacje i dopiero na końcu ją zapisuje ponownie do pamięci. W mikrokontrolerach w międzyczasie może zostać wywołane przerwanie, które na tej zmiennej może pracować. Tutaj następuje problem, bo zmienna w pamięci podczas przerwania nie będzie zgadzała się ze zmienną wczytaną do rejestru i wszystko się rozjedzie.

Zmienne globalne używane w przerwaniu musimy zadeklarować jako volatile. Zmiennych lokalnych w przerwaniu nie deklarujemy z volatile.

Czyli:

Volatile char zmienna;

przerwanie()

{

char zmienna2; //zmienna lokalna nie potrzebuje volatile

zmienna=zmienna+1;

}

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

@Bobby, czyli te argumenty można traktować jak stałe ale tylko dla danej funkcji? Bo w sumie zdanie które przytoczyłem "[...]zwykłe zmienne w funkcji z tym że mają one przypisaną wartość podczas wywoływania funkcji." byłoby logiczne dla stałych.

@MirekCz, jako że przykład a rozumiem to w żaden sposób nie mogę pojąć b i c, ale to wyłącznie przez to że jeszcze nie doszedłem do np. wskaźników... Twój post zostawię sobie na "później" jak zrozumiem kilka innych rzeczy. 🙂

pozdrawiam i dziękuję za dotychczasowe odpowiedzi... 🙂))

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

zwykłe zmienne w funkcji z tym że mają one przypisaną wartość podczas wywoływania funkcji." byłoby logiczne dla stałych.

To jest zwykła zmienna z początkową wartością taką jak przy wywoływaniu funkcji,w danej funkcji można na tej zmiennej wykonać operacje np:

duration = duration + 2
  • Pomogłeś! 1
Link do komentarza
Share on other sites

W funkcjach generalnie masz dostęp do dwóch rodzajów danych:

a) Dane globalne - dostępne z poziomu całej aplikacji. Tutaj można też w pewnym sensie "wpisać" dane do których masz wskaźnik.

b) Dane lokalne - zdefiniowane w obrębie funkcji i znikające jak funkcja się kończy. Zmienne będące argumentami funkcji są lokalne (czyli tworzona jest kopia tych danych przy wywoływaniu funkcji) i na koniec funkcji po prostu znikają - nigdy nie wracają do kodu który funkcję wywołał

a) zostają po wyjściu z funkcji, b) znikają. Koniec.

Link do komentarza
Share on other sites

Harnas, nie kumam :| Napisałeś to dokładnie tak jak jest w książce... Bo czym się różni to co napisałeś od np. tego:

void funkcja() //funkcja bez parametrów, nic nie zwraca
{
int duration=1; //zmienna która ma wartość początkową 1, później mogę normalnie wykonywać operacje na tej funkcji


//dalsza część programu
}

MirekCz, czyli chodzi o to samo dokładnie jak ze zwykłymi zmiennymi z tym że ja nadal nie wiem po co stosuje się parametry funkcji...

pzdr 😉))

Link do komentarza
Share on other sites

Bo chodzi o to, że wartość tej zmiennej dajesz przy wywołaniu funkcji.

Np.

obierz_ziemniaki(5);

możesz też dać tam zmienną, np:

int ziemniaki;

ziemniaki = 15;

obierz_ziemniaki(ziemniaki); // równoznaczne w tym wypadku z obierz_ziemniaki(15);

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

Mihau, Czyli generalnie jeśli zaraz po utworzeniu funkcji wypiszę zmienne np.

 void ziemniaki()
{
int i;
i=5

-dalsza cześć programu-

}

będzie to równoznaczne z

void ziemniaki(5)
{
-dalsza część programu-
}

zgadza się? W obydwu przypadkach zaraz po wywołaniu funkcji zmienne są dostępne od razu z daną wartością. W takim razie w jaki sposób odwołać się do tej zmiennej w drugim przypadku (5)?

Link do komentarza
Share on other sites

Ale mącisz. Funkcje są po to żebyś miał takie "czarne skrzynki" do których coś wkładasz, coś z nich wyjmujesz, a co się dzieje po drodze masz w nosie. Np.

int dodawanie(int a, int b) {
int wynik = a + b;
return wynik;
}


void main () {
int alamakota = dodawanie(5,6);
printf("%d", alamakota);
}

Powyższy kod wyświetli 11. Z punktu widzenia wywołania funkcji (w main) jest kompletnie nieistotne co się dzieje w jej środku. Ważne jest jedynie, że przyjmuje ona dwa argumenty w postaci int i zwraca wynik też w postaci int. Zmienne, które są argumentami funkcji to są zmienne nie stałe 😋, bo można zrobić np.

int dodawanie(int a, int b) {
a = a + b;
return a;
}

I da to taki sam rezultat jak w poprzednim przykładzie.

Kluczem do zrozumienia funkcji jest to, że najpierw musisz je zadeklarować, czyli opisać jak ma "czarna skrzynka" działać, a później tylko je wywołujesz, czyli podajesz odpowiednie parametry i czekasz na wynik.

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

mactro, No w końcu, takiej odpowiedzi oczekiwałem, pokazałeś w sposób zrozumiały dla mnie w jaki sposób odbywa się "wysłanie" i "zwrócenie" danych z funkcji i odwrotnie. Dokładnie o to mi chodziło, i już wiem na jakiej zasadzie działa ta "czarna skrzynka".

Dzięki wielkie, również pozostałym osobom dziękuję za odpowiedzi.

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.