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



Teraz jest 26 mar 2026, o 13:18


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 15 ] 
Autor Wiadomość
PostNapisane: 5 cze 2016, o 10:45 
Offline
Nowy

Dołączył(a): 24 mar 2016
Posty: 7
Pomógł: 0

Dzień dobry,

Mam pytanie j.w.
Chodzi dokładnie o kawałek kodu z niebieskiej książki:

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


Wiem że działa to tak że zostanie przyklejone C do słowa PORT, ale dlaczego?
Według mojego rozumowania dzieje się tak:
1. Wywołanie PORT(LCD_RSPORT) sprawi że zostanie podstawione za to SPORT(LCD_RSPORT).
2. Wywołanie SPORT(C) spowoduje podstawienie (PORT ## C).
Wiem że za LCD_RSPORT w 2 podpunkcie zostanie podstawiona litera C, tylko nie rozumiem dlaczego. Według mnie do tego makra powinno zostać podstawione tylko słowo LCD_RSPORT. Czy mógłby ktoś podać albo naprowadzić mnie na odpowiedź? Próbowałem szukać w internecie, ale nic nie znalazłem.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 11:42 
Offline
Użytkownik
Avatar użytkownika

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

Zobacz tutaj:
http://forum.atnel.pl/post974.html#p974
Pozdrawiam


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 12:00 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

Witam,
Virlantis napisał(a):
Wiem że za LCD_RSPORT w 2 podpunkcie zostanie podstawiona litera C, tylko nie rozumiem dlaczego.


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


czyli podmienia LCD_RSPORT ............ na C. (od tej linijki kodu można pisać LCD......, zamiast C. :)


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 12:20 
Offline
Nowy

Dołączył(a): 24 mar 2016
Posty: 7
Pomógł: 0

Wiem jak działa dyrektywa #define, programowałem już wcześniej sporo do konsoli, tak zaczynałem z językiem C i znam wszystkie podstawy, ale z takim zastosowaniem się nigdzie nie spotkałem. Spróbuję dokładniej opisać mój tok "rozumowania":

Jeśli napiszemy 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 otrzymamy PORTLCD_RSPORT, wniosek jest jeden, za LCD_RSPORT nie została podstawiona literka C, tak więc nic się nie stało. Kontynuując, pisząc podwójną makrodefinicję:

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


Wnioskuję, z poprzedniego kodu, że w pierwszej linijce otrzymamy:
PORT(LCD_RSPORT) SPORT(LCD_RSPORT), ponieważ makro to nie zamienia LCD na C, a więc do makra SPORT zostaje przekazany LCD_RSPORT i tam, tak samo jak we wcześniejszym makrze, nie może być mowy o rozwinięciu tego na literkę.

@edit:
Gdzieś musi się ładować #define LCD_RSPORT C, tylko nie wiem dlaczego i w którym dokładnie momencie się to dzieje.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 12:34 
Offline
Użytkownik
Avatar użytkownika

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

No to jeszcze raz:
post974.html#p974
Czy nie ma tam odpowiedzi na twoje pytanie?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 13:07 
Offline
Nowy

Dołączył(a): 24 mar 2016
Posty: 7
Pomógł: 0

Właśnie o to chodzi że tam jest napisane, że:

PORT(LED_PORT) SPORT(D)
SPORT(D) (PORT##D)

A wg. mnie nie jest to prawidłowe, ponieważ,
pierwsze makro nie spowoduje zamiany LED_PORT na D.

@edit:
@anshar:
Czytałem tamten wątek 3 razy i nie znalazłem odpowiedzi na moje pytanie, tam jest głównie opisane co robi to podwójne makro, mi chodzi tylko i wyłącznie o to jak się to dzieje.



Ostatnio edytowano 5 cze 2016, o 13:10 przez Virlantis, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 13:09 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

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


Po takim zapisie,
linijka 1.- od teraz zamienia LCD...... na C.

linijka 3.- podstawi za "x" - LCD...., a za LCD.... podstawi C, bo już ma linijkę 1.

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


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


dlatego operacje będą na "C". a nie na LCD...., bo to pośrednia 'nazwa' dla łatwiejszego rozeznania co ustawiamy.
Tak ja to zrozumiałem.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 13:13 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 27 mar 2015
Posty: 44
Pomógł: 2

rozpisze ci to po swojemu może rozeznasz

Kod:
    #define LCD_RSPORT    C           // tu nazywasz sobie (przyjazna nazwa ) LCD_RSPORT  - do którego przypisujesz literkę C nie port bo port by był
                                                                      PC...... a ty dajesz tylko C
 
    #define PORT(x) SPORT(x)                   // tu rezerwujesz nazwę PORT.... (kompilator zna PORTA,PORTB,PORTC itd bo ma je
                                                                    zarezerwowane  ) ale nie zna samego PORT do którego przypisujesz roboczą
                                                                     nazwę   SPORT

    #define SPORT(x) (PORT ## x   )             nazwę PORT tylko z końcówka -  ale jaką ? właśnie brak końcówki
                                                                    rozpiszmy to od końca nie stosując przyjaznej nazwy bo będzie dodatkowo mieszać tu
 
      #define PORT(C)  SPORT(C)
      #define SPORT(C) (PORT##C )             //  [##] -sklejenie liter do kupy co nam daje PORTC ! a to już zna kompilator

    PORT(LCD_RSPORT) &= ~(1<<LCD_RS);  // w tej linijce możesz używać: przyjaznej nazwy -LCD_RSPORT bądź bezpośrednio litere portu  C  ( co i tak kompilator za nas podstawi automatycznie )
                                                                    ,a co do LCD_RS to nie zdefiniowałeś numeru bita



Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 13:21 
Offline
Nowy

Dołączył(a): 24 mar 2016
Posty: 7
Pomógł: 0

@Daro69:

Tylko jeśli byśmy wtedy zapisali:

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


To wg tego co napisałeś wywołanie PORT(LCD_RSPORT) powinno zadziałać, ponieważ za x zostanie podstawione C i wszystko się ładnie skompiluje.

@SIND
Wiem co robi #define :D Umiem korzystać z tej dyrektywy z innych też, ale... dalej nie mogę pojąć... tych dwóch linijek kodu... ; )



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 15:16 
Offline
Moderator
Avatar użytkownika

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

anshar napisał(a):
No to jeszcze raz:
post974.html#p974
Czy nie ma tam odpowiedzi na twoje pytanie?


Ja uważam, że jest a kolega autor tego pytania chyba szczególnie omija TEN konkretny post w całym wątku:

post975.html#p975

gdzie najpierw wyjaśniłem jak to działa "po kolei" NIEBIESKIE kolorki i dlaczego nie może działać z jedną linijką (czerwony kolor na końcu posta)

proponuję to przeczytać i spróbować ew zadawać pytania czego z tego posta nie rozumiesz - zamiast wciąż powtarzać, że ty wiesz jak działa #define a tymczasem widać, że nie do końca wiesz

_________________
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: 5 cze 2016, o 15:39 
Offline
Nowy

Dołączył(a): 24 mar 2016
Posty: 7
Pomógł: 0

Czytałem tamten post 3 razy i nie mogę rozkminić ciągle, dlaczego w
PORT( LED_RWPORT ) SPORT(C)
jest zamienione na C, a dlaczego w
PORT( LED_RWPORT ) ( PORT ## LED_RWPORT )
tak się nie dzieje.
Wiem już że to zadziała, ale chciałbym to zrozumieć... :/



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 15:54 
Offline
Moderator
Avatar użytkownika

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

Virlantis napisał(a):
a dlaczego w
PORT( LED_RWPORT ) ( PORT ## LED_RWPORT )
tak się nie dzieje.


No to jeszcze raz - zobacz sam ;) .... w takiej wersji co sklejasz ?

napis PORT sklei ci się ze stałą dosłowną LED_RWPORT, czyli otrzymasz

PORTLED_RWPORT

## to sklejanie nazw po lewej i po prawej dla #define

to nie ważne, że wcześniej zrobiłeś sobie np

#define LED_RWPORT D

preprocesor sklei tylko nazwę LED_RWPORT

żeby było inaczej trzeba w jakiś sposób przekazać tę nazwę za pomocą ARGUMENTU i po to druga tajemnicza linijka, czyli

#define PORT(x) SPORT(x)

która nic nie robi poza tym, że bierze sobie jako x nazwę LED_RWPORT ale wywołując kolejne makro

#define SPORT(x) (PORT##x)

preprocesor widzi, że może rozwinąć tę nazwę LED_RWPORT do postaci D bo teraz ma szansę zauważyć , że to jest makro i pod nazwą LED_RWPORT kryje się D

wtedy przekazuje już za pomocą SPORT( D ) do PORT##D

można to rozpisać tak:

PORT(LED_RWPORT) SPORT(LED_RWPORT)
SPORT(D) (PORT##D)

czyli dostaniemy:

PORTD



a wracając jeszcze raz do twojego przypadku gdyby rozpisać co robi preprocesor

#define LED_RWPORT D
#define PORT( x ) ( PORT ## x )

już chyba sam się domyślasz - na początek weźmie też nazwę LED_RWPORT ale nie ma kiedy jej rozwinąć (wykonać makra) i dlatego odbędzie się to tak

PORT( LED_RWPORT ) ( PORT ## LED_RWPORT )

co da w wyniku

PORTLED_RWPORT

_________________
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: 5 cze 2016, o 16:03 
Offline
Nowy

Dołączył(a): 24 mar 2016
Posty: 7
Pomógł: 0

Chyba sens mojego problemu tkwi w tym, dlaczego preprocesor nie ma czasu aby ten zamiennik rozwinąć?
Bo to jest powodem dla którego jednostopniowe makro nie działa.

@edit:

Problem rozwiązany, wklepałem w C: :B

#define SPORT(x) (x ## PORT) i pod tym
#define SPORT(x) (PORT ## x) a pod tym

i w pierwszym wypadku zamiennik się rozwinął, w drugim nie, czyli wygląda na to, że dyrektywa ## blokuje rozwinięcie zamienników.



Ostatnio edytowano 5 cze 2016, o 16:19 przez Virlantis, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 cze 2016, o 16:17 
Offline
Moderator
Avatar użytkownika

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

Virlantis napisał(a):
dlaczego preprocesor nie ma czasu aby ten zamiennik rozwinąć?

To nie jest kwestia, że nie ma czasu ....

preprocesor to tak na prawdę tępy i głupi sługa króla kompilatora ;) ... i najpierw tak jak umie po kolei linia po linii wykonuje operacje

tu nie może wręcz rozwinąć makra LED_RWPORT - musisz zrozumieć zasadę działania operatora ## on skleja od razu to co ma po lewej i prawej:

PORT( LED_RWPORT ) ( PORT ## LED_RWPORT )


inaczej działa operator równania - gdybyś zrobił np

#define STALA 8

#define LICZBA = STALA

to rzeczywiście LICZBA przyjmie wartość = 8

a przy sklejaniu musimy najpierw wyłuskać tę wartość i robimy to pierwszym makrem

PORT(x) SPORT(x)

w tym kroku do SPORT też trafi LED_RWPORT ale gdy w kolejnej linii preprocesor będzie wywoływał makro

SPORT(x)

to TU właśnie może zobaczyć - hmm zaraz zaraz ta nazwa LED_RWPORT to makro z którego wynika, że powinienem wziąć pod uwagę to co w nim jest czyli D

no a końcówkę opowieści zakończonej happy andem już znasz ;) bo makro przekaże teraz do sklejenia już literkę D

( PORT ## D )

a nie nazwę makra


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: 5 cze 2016, o 16:33 
Offline
Nowy

Dołączył(a): 24 mar 2016
Posty: 7
Pomógł: 0

Tak teraz już wszystko rozumiem.
do PORT(x) trafia LED_RSPORT, a rozwinięcie jej jest blokowane przez ##, po to zastosowane jest drugie makro, żeby pierwsze mogło dokonać rozwinięcia treści a drugie dopiero jak dostanie D to wszystko skleić w całość.

wywołanie: PORT(LED_RSPORT) > po zadziałaniu pierwszego makra: SPORT(D) > po zadziałaniu drugiego makra: PORT ## D , zamiast:
wywołanie: PORT(LED_RSPORT) > po zadziałaniu pierwszego makra: (PORT ## LED_RSPORT) , a tutaj treść nie może się rozwinąć i tak pozostaje jego nazwa podczas klejenia :D

Dziękuję za cierpliwość, czas i wyjaśnienie ;)
Pozdrawiam :)



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

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