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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.