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



Teraz jest 21 lut 2025, o 05:48


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 9 ] 
Autor Wiadomość
PostNapisane: 4 maja 2015, o 21:17 
Offline
Użytkownik

Dołączył(a): 02 maja 2015
Posty: 62
Pomógł: 0

Witam!
Zaczynam uczyć się programowania, choć dobijam już do 50-tki, a elektroniką zająłem się będąc nastolatkiem.

Korzystam z BB i niektórych przykładów zawartych w książce nie potrafię zrozumieć.
Przeszukałem forum i znalazłem kilka wątków na ten temat, jednak wyjaśnienia nie znalazłem.
Do rzeczy więc!

strona 58
Kod:
extern int a1;
int b1;

Czym różnią się te dwa zapisy (oprócz słowa extern) że pierwszy jest deklaracją, a drugi definicją?

strona 59
Kod:
int max(int a, int b)
{
  return (a>b) ? a : b;
}

Co określa, że funkcja ma zająć "tym razem" obszar pamięci FLASH?

strona 110
Kod:
#include <avr/io.h>    //import pliku nagłówkowego

uint8_t zapal_bit(uint8_t nr);  //deklaracja funkcji

//**************************************************
int main(void)         //funkcja główna programu
{
  DDRB = 0xFF          //ustawienie całego portu B jako wyjście

  PORTB = zapal_bit(5)   / wywołanie funkcji i wynik na port B

}
//**************************************************

uint8_t zapal_bit(uint8_t nr)  //definicja funkcji
{
  uint8_t temp;
  temp =(1<<nr);

  return temp;      //koniec funkcji, zwrot wyniku
}

Nie rozumiem dlaczego jako argument funkcji zapal_bit raz jest użyta zmienna nr, a innym razem stała dosłowna 5?
Dlaczego zmienna nr nie jest zainicjowana i jaką przyjmuje wartość?

Autor kilka razy podkreśla, że te kwestie trzeba w 100% zrozumieć, więc pytam i będę wdzięczny za wyjaśnienia.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2015, o 21:22 
Offline
Moderator
Avatar użytkownika

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

oowan napisał(a):
Autor kilka razy podkreśla, że te kwestie trzeba w 100% zrozumieć, więc pytam i będę wdzięczny za wyjaśnienia.

Ja przede wszystkim dziękuję za pytania i pomimo to, że starałem się to wyjaśnić w książce - a być może mi nie wyszło do końca jeśli chodzi o kolegę - to tym bardziej doceniam pytanie - zamiast męczenie się gdzieś po kątach. Z chęcią spróbuję tutaj doprecyzować - może mi się uda - a jeśli nie mnie to może jeszcze inne osoby podpowiedzą/opowiedzą to swoimi słowami.

oowan napisał(a):
Co określa, że funkcja ma zająć "tym razem" obszar pamięci FLASH?

Zacznę od tego co na str 59. Zobacz - gdy nie ma w kodzie ciała funkcji i mamy TYLKO jej nagłówek:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

(widzisz ? kończy się średnikiem) .... to to jest DEKLARACJA funkcji. Nie ma kodu funkcji, nie ma jej ciała - więc nie może to być jej DEFINICJA. Ale jeśli zobaczysz w kodzie:

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


czyli nawiasy klamrowe w których widzisz kod źródłowy tej funkcji czyli jej "ciało" no to na ten kod potrzebna jest pamięć FLASH nieprawdaż ? trzeba gdzieś go przetłumaczyć na asembler i umieścić w pamięci aby mógł się ten kod wykonywać. I to jest DEFINICJA funkcji.

------------------------ [ Dodano po: 4 minutach ]

oowan napisał(a):
Czym różnią się te dwa zapisy (oprócz słowa extern) że pierwszy jest deklaracją, a drugi definicją?

Ze zmiennymi jest troszkę inaczej, bo przecież zmienna to zmienna , nie ma ona żadnego kodu źródłowego prawda? Więc każde wystąpienie zmiennej nie poprzedzonej słówkiem extern, oznacza, że jest to jej DEFINICJA - czyli kompilator zarezerwuje na tę zmienną miejsce w pamięci RAM, lub FLASH lub EEPROM zależnie jak ją zdefiniujesz.

Specyfikator extern dodajemy w plikach nagłówkowych *.h bo to te pliki inkludujemy w ramach projektu. Tu musisz doczytać jeszcze w książce o podziale projektu na pliki żeby się lepiej wyjaśniło. Ale kontynuując - jeśli chcesz aby jakaś zmienna, którą zdefiniowałeś sobie w pliku np keyb.c

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


była dostępna w innym pliku *.c to musisz w tymże innym pliku zainkludować plik keyb.h .... a w nim podpowiedzieć kompilatorowi, że gdzieś w projekcie jest definicja zmiennej o nazwie "a"

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


dzięki czemu będziesz mógł w tym innym pliku *.c korzystać z tejże zmiennej.

------------------------ [ Dodano po: 12 minutach ]

oowan napisał(a):
Nie rozumiem dlaczego jako argument funkcji zapal_bit raz jest użyta zmienna nr, a innym razem stała dosłowna 5?
Dlaczego zmienna nr nie jest zainicjowana i jaką przyjmuje wartość?


Uwaga! wyróżniamy coś takiego jak

DEKLARACJĘ funkcji
DEFINICJĘ funkcji

ale jeszcze jest coś takiego jak wywołanie tejże funkcji gdzieś później w kodzie.

jeśli więc masz funkcję

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


to nazwa argumentu "st" jest parametrem formalnym w tym przypadku - i taką nazwą "st" posługujesz się w kodzie źródłowym (w ciele tej funkcji)

Natomiast tę funkcję wywołujemy później gdzieś w kodzie np tak:

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


albo

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


i zobacz - pokazałem ci dwa wywołania funkcji w kodzie - do której przekazaliśmy parametry aktualne - czyli nazwy z kodu z funkcji nadrzędnej albo stałe dosłowne. W pierwszym przypadku do ciała funkcji trafi argument o wartości 'a' a w drugim przypadku argument o wartości 'P'

ten sam przykład ale z liczbami a nie znakami ASCII

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


i wywołania gdzieś w kodzie:

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


albo np:

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


Jak widzisz - nazwy parametrów FORMALNYCH absolutnie nie muszą być takie same jak AKTUALNYCH. Ba! w przypadku stałych dosłownych przecież nawet w ogóle nie przekazujemy nazwy fun1( 6 ); prawda ? ;)

Argumenty służą tylko do przekazania wartości albo wskaźnika

------------------------ [ Dodano po: 15 minutach ]

Na koniec dodam - że to co tu piszę - także napisane jest w książce - ale może zatrzymałeś się czytając - a tymczasem za kilka stron właśnie o tym będzie ;) Dlatego zawsze powtarzam - tę książkę warto najpierw JEDEN RAZ przeczytać w całości. Nie po to żeby zapamiętać wszystko bo nie da rady. Ale przynajmniej utkwi w pamięci - że gdy trafisz na coś niezrozumiałego czytając później drugi raz na spokojnie - że na pewno ciut dalej będzie o tym mowa ale już z przykładami ;)

------------------------ [ Dodano po: 22 minutach ]

Przy okazji - nieco inne spojrzenie na parametry formalne i aktualne - może też się przyda dla lepszego zrozumienia ;)

http://polska.superhost.pl/funkcje2.htm

_________________
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  
PostNapisane: 6 maja 2015, o 21:39 
Offline
Użytkownik

Dołączył(a): 02 maja 2015
Posty: 62
Pomógł: 0

mirekk36 dziękuję za wyjaśnienia. Trochę mi się rozjaśniło, ale jeszcze nie wszystko.

na str 59.
oowan napisał(a):
Co określa, że funkcja ma zająć "tym razem" obszar pamięci FLASH?

mirekk36 napisał(a):
... widzisz kod źródłowy tej funkcji czyli jej "ciało" no to na ten kod potrzebna jest pamięć FLASH nieprawdaż ? trzeba gdzieś go przetłumaczyć na asembler i umieścić w pamięci aby mógł się ten kod wykonywać...

Myślałem, że przestrzeń pamięci dla "ciała" funkcji rezerwowana jest w RAMie.
Czyli, że to kompilator rezerwuje przestrzeń pamięci już w pliku wsadowym?


na str 110.
Wszystkie przykłady, które podałeś są dla mnie jasne. Jednak dalej nie mogę rozgryźć tego konkretnego przykładu na str. 110.
Jest tu jakby skrót myślowy i do mnie to nie dociera.

Jak napisałeś zmienna nr występująca w deklaracji funkcji zapal_bit , jest zmienną formalną.
Ale występuje ona też jako argument przesunięcia bitowego w ciele funkcji zapal_bit .
Żeby wykonać przesunięcie, zmienna nr chyba musi już mieć konkretną wartość.
Czy wartość do zmiennej może być przekazana przez wywołanie funkcji?
Kod:
PORTB = zapal_bit(5)

bo innej możliwości tu nie widzę.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 maja 2015, o 22:46 
Offline
Moderator
Avatar użytkownika

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

oowan napisał(a):
Myślałem, że przestrzeń pamięci dla "ciała" funkcji rezerwowana jest w RAMie.
Czyli, że to kompilator rezerwuje przestrzeń pamięci już w pliku wsadowym?

Posłuchaj - w tych mikrokontrolerach to NIEMOŻLIWE, kod programu może być TYLKO I WYŁĄCZNIE w pamięci programu czyli pamięci FLASH, to wynika z ich konstrukcji.

oowan napisał(a):
bo innej możliwości tu nie widzę.

No dokładnie dane przekazujesz do funkcji przez argumenty aktualne, w tym przypadku

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


przekazujesz wartość = 5 (pięć to tzw STAŁA DOSŁOWNA)

a w tym przypadku

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

przekazujemy do funkcji wartość jaką ? no 17 ;)

------------------------ [ Dodano po: 1 minucie ]

oowan napisał(a):
Jest tu jakby skrót myślowy i do mnie to nie dociera.


To nie jest skrót myślowy - to są różnice pomiędzy parametrami aktualnymi i formalnymi. Parametrem formalnym (jego nazwą) posługujesz się wewnątrz funkcji - w jej ciele. Zaś do funkcji przekazujesz parametr aktualny, który nie musi mieć żadnej nazwy, bo można go przekazać za pomocą jak widzisz nawet stałej dosłownej.


Autor postu otrzymał pochwałę

_________________
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  
PostNapisane: 8 maja 2015, o 20:58 
Offline
Użytkownik

Dołączył(a): 02 maja 2015
Posty: 62
Pomógł: 0

Chyba wreszcie to zrozumiałem :idea: Dzięki!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 maja 2015, o 21:22 
Offline
Użytkownik

Dołączył(a): 02 maja 2015
Posty: 62
Pomógł: 0

Witam!
Trafiłem na kolejną rzecz, która mi jakoś nie pasuje.

Na stronie 150 jest poniższy przykład:

Kod:
int tab[] = { 7, 4, 5 };  // definicja tablicy 3-elementowej tab
void funkcja(int t[]);    // deklaracja funkcji z tablicą jako argument
funkcja(tab);  wywołanie w kodzie programu i przekazanie tablicy tab


W przytoczonym kodzie występują dwie różne tablice - o nazwach "tab" oraz "t".
Jednak z wyjaśnienia w książce, poniżej tego przykładu, wynika, że we wszystkich trzech liniach chodzi o tę samą tablicę.

Jak to jest, bo nie łapię?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 maja 2015, o 21:32 
Offline
Moderator
Avatar użytkownika

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

posłuchaj - teraz to może musisz doczytać czym różnią się argumenty/parametry formalne od aktualnych, bo widzę, że tu masz problem

tab - to nazwa tablicy

void funkcja(int t[]); - to tylko DEKLARACJA funkcji i jej argument formalny, który WCALE nie musi mieć takiej nazwy jak argument aktualny

funkcja(tab); - to już wywołanie tej funkcji - tyle że z argumentem aktualnym ....


Autor postu otrzymał pochwałę

_________________
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  
PostNapisane: 26 maja 2015, o 07:24 
Offline
Użytkownik

Dołączył(a): 02 maja 2015
Posty: 62
Pomógł: 0

mirekk36 napisał(a):
teraz to może musisz doczytać czym różnią się argumenty/parametry formalne od aktualnych, bo widzę, że tu masz problem

Aaa... rzeczywiście, nie wpadłem na to, że tablice też mogą być argumentami formalnymi.

Przyznam, że argumenty/parametry formalne są dla mnie bardzo nieintuicyjne - niby argument jest, ale go nie ma (a może odwrotnie) :roll:

Mirek, dziękuję za podpowiedź.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 20 gru 2015, o 21:30 
Offline
Użytkownik

Dołączył(a): 02 maja 2015
Posty: 62
Pomógł: 0

Witam po dłuższej przerwie!
Przeczytałem drugi raz (zgodnie z sugestią kolegów) teorię w BB i dotarłem do "części warsztatowej".
Tu znowu trafiłem na jakby, nieścisłość i proszę o wyjaśnienie.

Chodzi o fragment kodu odczytu danych z układu PCF8583 przez TWI:
Kod:
// definiujemy sobie dla polepszenia czytelności programu typ wyliczeniowy
   // wskazujący nam później na odpowiednie indeksy w tablicy (buforze)
   enum {ss, mm, hh};

Zgodnie ze składnią podaną w BB w części opisującej typ wyliczeniowy, brakuje tu nazwy między słowem enum, a lewym nawiasem klamrowym.
Kod:
enum nazwa_typu {wartosc1, wartosc2, ......., wartoscN}

Jakie znaczenie ma taki zapis?



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

Strefa czasowa: UTC + 1


Kto przegląda forum

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


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:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO