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



Teraz jest 4 wrz 2025, o 00:20


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 14 ] 
Autor Wiadomość
PostNapisane: 30 paź 2017, o 09:51 
Offline
Użytkownik

Dołączył(a): 13 mar 2013
Posty: 123
Pomógł: 1

Witam
W swoim projekcie chciałem wykorzystać kod z greenbooka do sterowania silnikiem krokowym, zapisując go jako moduł w dwóch plikach *.c i *.h. Problem zaczął się gdy doszedłem do zmiennej zapisanej jako typ enum. W oryginale deklarowany jest typ enum edir ( lewo, prawo) oraz za chwilę tworzona zmienna enum edir dir = lewo.
Ponieważ dostęp do zmiennej dir będzie mi potrzebny w innych modułach programu wiec muszę tę zmienną ujawnić w pliku *.h. I tu zaczynają się schody.
Pomyślałem,że enum edir (lewo,prawo) jest właściwą deklaracja i umieściłem ją w *.h , jednak kompilator mówi ,że jest to pusta deklaracja (empty). Oprócz tego umieszczenie zmiennej dir w pliku *.h jest też traktowane jako błąd.
Jak umieścić deklarację i definicją tego typu i należącej do niego zmiennej w plikach *.c i *.h, tak aby była zmienną globalną dla wszystkich modułów?
Będę bardzo zobowiązany z pomoc i wytłumaczenie zagadnienia , bo nieco się pogubiłem.
Pozdrawiam
W



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2017, o 09:56 
Offline
Moderator
Avatar użytkownika

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

MisterWhite napisał(a):
Ponieważ dostęp do zmiennej dir będzie mi potrzebny w innych modułach programu wiec muszę tę zmienną ujawnić w pliku *.h. I tu zaczynają się schody.
Pomyślałem,że enum edir (lewo,prawo) jest właściwą deklaracja i umieściłem ją w *.h , jednak kompilator mówi ,że jest to pusta deklaracja (empty). Oprócz tego umieszczenie zmiennej dir w pliku *.h jest też traktowane jako błąd.

Nie ma żadnych schodów ;) lepiej pokaż w kodzie jak ty to robisz - jakiś krótki przykład typu nazwa pliku i co gdzie umieszczasz i jak .... Bo na podstawie takiego opisu to można gdybać gdybać przypuszczać i gdybać ;)

_________________
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: 30 paź 2017, o 10:06 
Offline
Użytkownik

Dołączył(a): 02 gru 2015
Posty: 550
Pomógł: 28

W blue booku na stronie 84 masz to opisane a w kodzie lekcja 15 PetitFS masz przykład jak to zrobić szukaj takiej zmiennej jak FRESULT i tam w pliku phh.h masz pokazane jak to zrobić.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2017, o 13:10 
Offline
Użytkownik

Dołączył(a): 13 mar 2013
Posty: 123
Pomógł: 1

Dzięki wielkie za podpowiedź, ale w przykładzie 15 PetitFS jest to znacznie bardziej zaawansowane, z użyciem typedef. Natomiast ja chciałem wykorzystać znacznie prostszą konstrukcję która była umieszczona w przykładzie 13. Więc w pliku wtmotorstep.h wstawiłem:

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


natomiast w pliku wtmotorstep.c

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


W MKclipse kompilator się buntuje:

    STEPMOTOR/wtmotorstep.h:32:1: warning: empty declaration [enabled by default]
    enum edir {motor_left, motor_stop, motor_right };
    ^
I dalej:
    STEPMOTOR/wtmotorstep.c:14:6: error: parameter 'dir' is initialized
    enum edir dir = motor_stop ;
    ^
i kolejny komumnikat dotyczący tego samego ale inaczej sformułowany:

    STEPMOTOR/wtmotorstep.c:14:11: error: redefinition of parameter 'dir'
    enum edir dir = motor_stop ;
    ^
Oraz ostatecznie:

    In file included from STEPMOTOR/wtmotorstep.c:9:0:
    STEPMOTOR/wtmotorstep.h:33:11: note: previous definition of 'dir' was here
    enum edir dir ;

Obawiam się ,że ja po prostu nie rozumiem do końca co jest deklaracją a co definicją i w którym momencie jest rezerwowana pamięć dla typu enum. Niestety na stronie 84 temat został wprawdzie bardzo ładnie opisany ale akurat zagadnienie związane z definicja /deklaracja dla enum nie zostało rozwinięte.
Pozdrawiam
W



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2017, o 13:44 
Offline
Użytkownik
Avatar użytkownika

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

W tym przypadku zdecydowanie potrzebny jest większy wycinek tego co napisałeś.
Bo nie wiadomo czy te wpisy to w funkcjach, czy w pliku źródłowym, a może też i nagłówkowym



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2017, o 13:54 
Offline
Moderator
Avatar użytkownika

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

no tak rzeczywiście nie wiesz czym różni się DEFINICJA od DEKLARACJI zmiennej - a jest to OPISANE w Bluebooku - zajrzyj więc do książki i powiedz, czego nie rozumiesz z tego opisu - bo sorki jeśli chodzi o mnie nie mam już siły ale też czasu żeby po raz 625476-ty opisywać to samo i pokazywać na forum a nie dalej jak kilka dni temu to znowu komuś wyjaśniałem ... Tyle że żeby wyjaśniać to napisz czego z książki nie rozumiesz - z tego wyjaśnienia różnic dla zmiennych

i tak jak kolega wyżej pisze pokazałbyś więcej kodu - bo z tego co jest - to pomimo, że z błędami to i tak to się skompiluje bez żadnych błędów - więc coś jeszcze masz mega namieszane

_________________
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: 30 paź 2017, o 14:50 
Offline
Użytkownik

Dołączył(a): 13 mar 2013
Posty: 123
Pomógł: 1

Sorry, nie chciałem zaśmiecać .Podaję cały kod modułu dotyczący sterowania silnikiem krokowym
Plik wtmotorstep.h
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


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


W zasadzie jest to prawie czysty kod z książki , pozbawiony flag związanych z automatyczna zmianą obrotów i z dodaną funkcja callback która w założeniu będzie miała ustalać wartość zmiennej dir.

Jeśli chodzi o moje rozumienie różnic pomiędzy deklaracja a definicją to tak jak ja to rozumiem, deklaracja (na podstawie podanego typu zmiennej czy funkcji) rezerwuje pamięć dla tej zmiennej lub funkcji. W wypadku funkcji niezbędne jest podanie jeszcze jakie i jakiego typu zmienne będą brały udział w tej funkcji. Wszystko to oczywiście w celu zarezerwowania odpowiedniego miejsca w pamięci.
Natomiast definicja jest już po prostu ciałem funkcji czyli jej realizacją.
Natomiast w przypadku enum nie jest dla mnie jasne skąd kompilator ma wiedzieć ile pamięci zarezerwować, czy należy to traktować jako stałą tekstową, czy biorąc pod uwagę że dla typu enum można podawać też kolejne liczby, kompilator traktuje je jako stałe typu int?
Poza tym nie do końca jest dla mnie jasna zasada tworzenia zmiennej dir przymierającej wartości z zakresu edir. Zgodnie z podpowiedzią spróbuję może przypomnieć sobie zasady rządzące typedef, może coś to wyjaśni.
To jest dla mnie niejasne.
Pozdrawiam
W



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2017, o 15:16 
Offline
Moderator
Avatar użytkownika

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

MisterWhite napisał(a):
deklaracja (na podstawie podanego typu zmiennej czy funkcji) rezerwuje pamięć dla tej zmiennej lub funkcji.

No to zobacz - w książce NIC TAKIEGO nie ma ;) skąd ty to wziąłeś ? .... widzisz przy takim podejściu będzie ciężko, no ale skoro już się zabrałeś za książkę to jeszcze raz z uporem maniaka powtórzę

DEFINICJA - rezerwuje pamięć i to zarówno w przypadku zmiennych jak i funkcji ... eeeeh ileż razy to trzeba powtarzać tym bardziej, że jest w książce.

A zatem DEFINICJA to ciało funkcji natomiast DEFINICJA zmiennej to: TYP + NAZWA ZMIENNEJ;

to samo dotyczy zmiennej enum - a to, że nie orientujesz się ile ma miejsca zająć - to co za problem zdefiniować skompilować i zobaczyć o ile więcej bajtów przybyło w RAM ? No toż to najprostszy sposób ... Później zakomentuj i sprawdź ile ubyło RAM - no i już wiesz

DEKLARACJA to w przypadku funkcji - jest sam NAGŁÓWEK funkcji - często w pliku nagłówkowym *.h

natomiast DEKLARACJA zmiennej ? ..... no tu zęby zjadają początkujący - tylko dziwię się dlaczego skoro to jest ŁADNIE opisane w Bluebooku

deklaracja zmiennej charakteryzuje się słówkiem (specyfikatorem) "extern" który podajemy w pliku nagłówkowym *.h i deklaracja NIGDY nie spowoduje rezerwacji pamięci

----------------------

a teraz otwórz książkę i sprawdź bo jest w niej to samo tyle że jeszcze z przykładami

_________________
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: 30 paź 2017, o 16:07 
Offline
Użytkownik

Dołączył(a): 13 mar 2013
Posty: 123
Pomógł: 1

Serdecznie dziękuję za wyjaśnienie . Mój błąd wziął się zapewne ze złego rozumienia pracy kompilatora. Ja po prostu wyobrażałem sobie ,że przed utworzeniem zmiennej bądź funkcji musi on sobie przygotować miejsce w pamięci i potrzebna mu do tego deklaracja. Ot taka próba wyjaśnienia na "chłopski rozum".
No ale teraz wszystko jasne. Jeszce raz dziękuję. Spróbuję w domu poprawić kod na podstawie nowej wiedzy.
A swoją drogą zastanawia mnie jaką rolę pełni deklaracja i dlaczego jest kompilatorowi niezbędna. Czyżby chodziło o to by w trakcie kompilacji mógł po natrafieniu na jakąś nazwę funkcji lub zmiennej po prostu ją zidentyfikować i zorientować się w którym pliku szukać jej definicji? Czy znów mam błędne wyobrażenie?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2017, o 16:13 
Offline
Użytkownik
Avatar użytkownika

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

mirekk36 napisał(a):
DEKLARACJA to w przypadku funkcji - jest sam NAGŁÓWEK funkcji - często w pliku nagłówkowym *.h

natomiast DEKLARACJA zmiennej ? ..... no tu zęby zjadają początkujący - tylko dziwię się dlaczego skoro to jest ŁADNIE opisane w Bluebooku

deklaracja zmiennej charakteryzuje się słówkiem (specyfikatorem) "extern" który podajemy w pliku nagłówkowym *.h i deklaracja NIGDY nie spowoduje rezerwacji pamięci


Ja chyba wiem skąd ta konsternacja bierze, sam się zwykle na to łapię :). Jeśli poprawnie zdefiniujemy zmienną w pliku źródłowym, to w nagłówkowym nie damy extern to też to zadziała. Człowiek naogląda się takich kodów, a potem mu się wszystko plącze :) Dlatego ja staram się zawsze pisać to extern :)

Mam podejrzenie o co głównie chodzi autorowi wątku. Pomimo, że już trochę programuję to pomimo tego dostaję oczopląsu, jeśli widzę typ wyliczeniowy :)

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


to nie mam kłopotu: po lewej mam typ danych, a po prawej nazwa zmiennej wraz z inicjalizacją.

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

to też zwykle nie mam kłopotu i możemy zdefiniować nowa zmienną, o nowym typie:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


To nadal mamy jasność po lewej to, a po prawej to.

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


mamy konsternację, czemu do jasnej anielki :) mamy definicję taką:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Czemu mamy "enum edir dir" ?

Po lewej stronie mamy raz: enum, dwa: edir, trzy: dir i dopiero inicjalizacja, przypisanie wartości.

To jest ten OCZOPLĄS, jak dla mnie :)
Teraz nie odpowiem na to pytanie, bo muszę iść, ale wieczorem siadam do książek i szukam szczegółowej odpowiedzi :)


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2017, o 16:19 
Offline
Moderator
Avatar użytkownika

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

Zealota napisał(a):
Ja chyba wiem skąd ta konsternacja bierze, sam się zwykle na to łapię . Jeśli poprawnie zdefiniujemy zmienną w pliku źródłowym, to w nagłówkowym nie damy extern to też to zadziała. Człowiek naogląda się takich kodów, a potem mu się wszystko plącze

Wiesz co? to bardzo słuszna diagnoza - a tym bardziej, że do dzisiaj nawet na naszym forum, zdarzają się ludzie, którzy zażarcie próbują wyjaśniać że "można" w plikach *.h definiować zmienne - no weź tu bądź mądry i pisz wiersze jak to się mówi ;)

MisterWhite napisał(a):
Czyżby chodziło o to by w trakcie kompilacji mógł po natrafieniu na jakąś nazwę funkcji lub zmiennej po prostu ją zidentyfikować i zorientować się w którym pliku szukać jej definicji? Czy znów mam błędne wyobrażenie?


masz dobre wyobrażenie ale przecież możesz sobie zawsze poza książką obejrzeć poradnik wideo - oglądałeś ten ?



na prawdę - jak obejrzysz to sporo więcej ci się wyjaśni


Zealota napisał(a):
Czemu mamy "enum edir dir" ?

No bo tak założono, że jeśli mamy stworzyć zmienną na podstawie zdefiniowanego typu wyliczeniowego to poza nazwą tego typu trzeba po lewej stronie jeszcze dodać to kocie "enum"

ja z tego W OGÓLE nie korzystam ;) albo bardzo rzadko - a w książce pokazałem no bo chyba warto wiedzieć, że tak też się robi w C nieprawdaż ? ;)

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

Zealota napisał(a):
To jest ten OCZOPLĄS, jak dla mnie

dla mnie też - dlatego ja tam wolę z typami enum pracować w dużo prostszy sposób

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


i tak dalej i tak dalej


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: 30 paź 2017, o 19:37 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 09 gru 2014
Posty: 1540
Pomógł: 269

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



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2017, o 22:38 
Offline
Użytkownik

Dołączył(a): 13 mar 2013
Posty: 123
Pomógł: 1

No dużo mi się wyjaśniło, teraz czuję że stoję na pewniejszym gruncie. Czasem mimo lektury niezbędne jest takie bardzo konkretne resume. Zabieram się też za oglądanie poradnika - śledzę je wszystkie od dawna, nie wiem w jaki sposób ten mi umknął.
Tym niemniej nie zmienia to faktu , że po uwzględnieniu tych wszystkich wiadomości program w dalszym ciągu się nie skompilował. Aby nie nadużywać Waszej cierpliwości wpadłem na pewien pomysł:
Założyłem nowy projekt o nazwie enum_Test składający się z katalogu Test zawierającego w sobie pliki Testerek.h i Testerek.c a także z pliku main.c w katalogu głównym.

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


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


czyli jedynie zawartość która generowała cały czas błędy - i skompilowało się bezbłędnie!!
Teraz będę dodawał kolejno wpisy które były poprzednio i zobaczę w którym momencie wyrzuci błąd - lub też nie.
Jeszcze raz dzięki za cierpliwość i pozdrawiam
W



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 paź 2017, o 06:50 
Offline
Moderator
Avatar użytkownika

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

MisterWhite napisał(a):
wpadłem na pewien pomysł:
Założyłem nowy projekt o nazwie enum_Test składający się z katalogu Test zawierającego w sobie pliki Testerek.h i Testerek.c a także z pliku main.c w katalogu głównym.

No widzisz a ja wciąż powtarzam ;) nie tylko na forum ale i w co którymś poradniku, żeby TAK właśnie robić - to się nazywa podział problemu na DWA ... od tego się zaczyna ... to podstawa podstaw ... i dzięki temu dużo szybciej udaje się rozwiązać problemy

_________________
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  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 14 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

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