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



Teraz jest 29 mar 2024, o 02:21


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 18 ] 
Autor Wiadomość
PostNapisane: 30 lis 2018, o 19:53 
Offline
Użytkownik

Dołączył(a): 31 lip 2016
Posty: 154
Pomógł: 4

Proszę o wyjaśnienie takiego zapisu:
Powołuję zmienną

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


Dlaczego to się kompiluje skoro powołana zmienna jest ośmio bitowa?
To jest kawałek programu.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 lis 2018, o 20:07 
Offline
Użytkownik
Avatar użytkownika

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

To jest właśnie siła języka C. Tu rządzi programista, ale niestety musi wiedzieć co robi, dlatego też zasady dotyczące wielkości zmiennych są bardzo elastyczne, a jedna z większej elastyczności to domyślna promocja do int.
Inaczej pisząc, to programista musi kontrolować zakres typów, a nie kompilator. Dzięki temu można robić "różne sztuczki" :)


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 lis 2018, o 20:08 
Offline
Użytkownik
Avatar użytkownika

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

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

powołujesz zmienną z wartością 0,
inkrementujesz do wartości 1,
oczekujesz na spełnienie 'ifa' który który nigdy się nie spełni, by ustawić wartość na PORTB.
poza ifem: zerujesz zmienną.

hmm. ale dlaczego nie krzyczy?
może dlatego że nie przypisujesz takiej wartości do zmiennej, a sprawdzać w ifie można cokolwiek :?
:)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 lis 2018, o 21:47 
Offline
Moderator
Avatar użytkownika

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

Daro69 napisał(a):
ja nie wiem dlaczego nie krzyczy.

A dlaczego miałby krzyczeć? Co szkodzi porównywać zawartość bajtu ze słowem ? Toż w zakresie 0-255 pokrywają się ich wartości ;) ... poza tym to co pisze wyżej kolega Zealota.

_________________
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 lis 2018, o 21:49 
Offline
Użytkownik
Avatar użytkownika

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

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

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


oprócz tego tam jest niepotrzebny średnik.
Dodatkowo promocja do int jednak zapewni, że warunek się spełni.
Można rzutować na int8_t i wtedy już nie będzie działać.
Tak z praktyki dopiero ostatnio widzę, co było dla mnie długo mgliste, ten wszędobylski int :)
Nie potrafię już na to patrzeć, że co chwilę trzeba rzutować, żeby nie przekroczyć zakresu int dla dużych liczb, a to powoduje farfocle, oczopląsy i długaśne linijki :)
Przy AVR to zwykle, żaden problem, bo tam rządzi uint8_t, ale przy tych stm,ach to już trzeba się strzec :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 08:35 
Offline
Użytkownik

Dołączył(a): 31 lip 2016
Posty: 154
Pomógł: 4

Zealota napisał(a):
To jest właśnie siła języka C. Tu rządzi programista, ale niestety musi wiedzieć co robi, dlatego też zasady dotyczące wielkości zmiennych są bardzo elastyczne, a jedna z większej elastyczności to domyślna promocja do int.
Inaczej pisząc, to programista musi kontrolować zakres typów, a nie kompilator. Dzięki temu można robić "różne sztuczki" :)

Nie rozumiem dlaczego promocja do int, skoro powołana zmienna jest określona uint8_t

------------------------ [ Dodano po: 2 minutach ]

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

powołujesz zmienną z wartością 0,
inkrementujesz do wartości 1,
oczekujesz na spełnienie 'ifa' który który nigdy się nie spełni, by ustawić wartość na PORTB.
poza ifem: zerujesz zmienną.

hmm. ale dlaczego nie krzyczy?
może dlatego że nie przypisujesz takiej wartości do zmiennej, a sprawdzać w ifie można cokolwiek :?
:)

A gdzie inkremenuję do wartości 1?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 09:30 
Offline
Użytkownik

Dołączył(a): 29 mar 2012
Posty: 595
Lokalizacja: Jaworzno
Pomógł: 39

W drugiej linii Twojego kodu, nie widzisz tego?;-)

_________________
Pozdrawiam
PP



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 10:54 
Offline
Użytkownik

Dołączył(a): 31 lip 2016
Posty: 154
Pomógł: 4

Piotrek_P napisał(a):
W drugiej linii Twojego kodu, nie widzisz tego?;-)

Tak w drugiej linii inkrementuję zmienną, ale nie do jednego a do 500.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 11:27 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 19 cze 2014
Posty: 820
Lokalizacja: Tam gdzie PYRY są
Pomógł: 64

zorro napisał(a):
uint8_t zmienna = 0;  //w przerwaniu wpisuję
zmienna++;
   if ( zmienna == 500 );
 
     PORTB = LED_TOG;
     zmienna = 0;


jak dla mnie nie zachodzi tu żadna promocja do int tylko zmienna jedzie sobie do 255 i się przepełnia i nigdy nie osiąga 500. Nikt nie zabroni sprawdzać czy jest równa nawet 10000000 bo dlaczego by nie. Po prostu zawsze będzie fałszywy warunek i już.
Poza tym warunek if ( zmienna == 500 ); jest pusty a reszta jest poza warunkiem, czyli port się togluje cały czas a zmienna zeruje się zawsze po 1.

Lepiej byłoby tak, choć wg mnie i tak się nie wykona warunek
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Cytuj:
A gdzie inkremenuję do wartości 1?

w każdym obiegu pętli. Na początku masz zmienna=0, potem zmienna++ czyli inkrementujesz do 1, potem pusty if, który i tak nigdy się nie wykona, następnie ZA KAŻDYM OBIEGIEM resetujesz zmienna.
 

_________________
IntegraMETEO
WordCLOCK
IntegraTOUCH



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 11:39 
Offline
Użytkownik
Avatar użytkownika

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

skalarro napisał(a):
jak dla mnie nie zachodzi tu żadna promocja do int tylko zmienna jedzie sobie do 255
 


Proponuję najpierw sprawdzić, kompilując kod.
Ja oczywiście sprawdziłem pod kompilatorem i dlatego jestem mądrzejszy.
To najlepsza forma nauki.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 11:48 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 19 cze 2014
Posty: 820
Lokalizacja: Tam gdzie PYRY są
Pomógł: 64

Zealota napisał(a):
Ja oczywiście sprawdziłem pod kompilatorem i dlatego jestem mądrzejszy.

No to muszę doczytać... DO tej pory żyłem w przekonaniu, że dotyczy to działań typu dodawanie i mnożenie dwóch zmiennych a nie zwykłego inkrementowania. ALe w sumie jakby się tak zastanowić to zmienna++ to też dodawanie dwóch liczb.
Nie zmienia to faktu, że w tym wypadku if się i tak nie wykona bo zmienna nie dojdzie nigdy nawet do 2, a warunek jest pusty

_________________
IntegraMETEO
WordCLOCK
IntegraTOUCH



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 11:55 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Proponuję poczytać np. to (dość przystępny opis):
https://opensourceforu.com/2016/06/quic ... omotion-c/

Ewentualnie wpisać w Google "c promotion rules" i pojawi się sporo artykułów na ten temat.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 12:48 
Offline
Użytkownik
Avatar użytkownika

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

skalarro napisał(a):
Zealota napisał(a):
Ja oczywiście sprawdziłem pod kompilatorem i dlatego jestem mądrzejszy.

No to muszę doczytać... DO tej pory żyłem w przekonaniu, że dotyczy to działań typu dodawanie i mnożenie dwóch zmiennych a nie zwykłego inkrementowania. ALe w sumie jakby się tak zastanowić to zmienna++ to też dodawanie dwóch liczb.
Nie zmienia to faktu, że w tym wypadku if się i tak nie wykona bo zmienna nie dojdzie nigdy nawet do 2, a warunek jest pusty


Jeszcze hola hola.
Być może wczoraj trochę jednak niepotrzebnie zamieszałem, przepraszam :(
Zrobiłem kolejne testy i na razie mojej tezy o tym, że dojdzie do warunku zmienna == 500, z powodu promocji do int, nie mogę wykazać niestety, pomimo pracy z kompilacją.
Zgodnie z sugestią Kolegi andrews również mnie się należy dokształcenie...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 18:43 
Offline
Użytkownik

Dołączył(a): 31 lip 2016
Posty: 154
Pomógł: 4

skalarro napisał(a):
zorro napisał(a):
uint8_t zmienna = 0;  //w przerwaniu wpisuję
zmienna++;
   if ( zmienna == 500 );
 
     PORTB = LED_TOG;
     zmienna = 0;


jak dla mnie nie zachodzi tu żadna promocja do int tylko zmienna jedzie sobie do 255 i się przepełnia i nigdy nie osiąga 500. Nikt nie zabroni sprawdzać czy jest równa nawet 10000000 bo dlaczego by nie. Po prostu zawsze będzie fałszywy warunek i już.
Poza tym warunek if ( zmienna == 500 ); jest pusty a reszta jest poza warunkiem, czyli port się togluje cały czas a zmienna zeruje się zawsze po 1.

Lepiej byłoby tak, choć wg mnie i tak się nie wykona warunek
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Cytuj:
A gdzie inkremenuję do wartości 1?

w każdym obiegu pętli. Na początku masz zmienna=0, potem zmienna++ czyli inkrementujesz do 1, potem pusty if, który i tak nigdy się nie wykona, następnie ZA KAŻDYM OBIEGIEM resetujesz zmienna.
 


Inkrementacja zmiennej jest umieszczona w przerwaniu, więc w każdym przerwaniu wzrasta o wartość jeden.
Skąd się wzięło u was inkrementacja do 1.
Zmienna zerowana jest po warunku if nie po każdym obiegu. Tak ja to widzę.

Chodził mi oto, że powołałem zmienną ośmio bitową a w przerwaniu w warunku if wpisałem wartość 500 i kompilator
nie wyświetlił mi błędu a skompilował. Ja myślałem, iż największą wartość jaką można wpisać to 255,
Jeden z kolegów wyjaśnił, iż to programista ma pilnować wartości wpisywanych do warunku if.
To co podałem w pierwszym poście to tylko wybrany fragment kodu.

Dzięki wszystkim za wypowiedzi.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 18:55 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 19 cze 2014
Posty: 820
Lokalizacja: Tam gdzie PYRY są
Pomógł: 64

zorro napisał(a):
Skąd się wzięło u was inkrementacja do 1.


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


Przeanalizuj co robi Twój warunek...

Albo zapisz go inaczej - będziesz widział co się dzieje"

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


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


Widzisz teraz skąd ta jedynka a nie 255 czy 500?

_________________
IntegraMETEO
WordCLOCK
IntegraTOUCH



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 19:03 
Offline
Użytkownik
Avatar użytkownika

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

zorro napisał(a):
Chodził mi oto, że powołałem zmienną ośmio bitową a w przerwaniu w warunku if wpisałem wartość 500 i kompilator
nie wyświetlił mi błędu a skompilował. Ja myślałem, iż największą wartość jaką można wpisać to 255

Wygląda na to, że w porównaniu kompilator nie sprawdza typu.

Gdyby zapisać 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 dostaniemy ostrzeżenie. Porównanie to oczywiście nie to samo co przypisanie wartości do zmiennej.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 19:16 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 19 cze 2014
Posty: 820
Lokalizacja: Tam gdzie PYRY są
Pomógł: 64

Zealota napisał(a):
Porównanie to oczywiście nie to samo co przypisanie wartości do zmiennej

Dokładnie. I to jest chyba podsumowanie tematu.
Bo kto programiście zabroni porównania np tak abstrakcyjnego i pozbawionego sensu jak if (zmienna== "elephant"){};

Można sprawdzić czy kolor_samochodu == kombi ;p
Oczywiście nie ma to sensu, typy niezgodne i nie mają prawa nigdy się zgodzić ale kompilator grzecznie to zaakceptuje a program ochoczo będzie sprawdzał warunek za każdym obiegiem... hehe

_________________
IntegraMETEO
WordCLOCK
IntegraTOUCH



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 gru 2018, o 20:38 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Zawsze można dodać do linii poleceń kompilatora opcję -Wtype-limits, która powinna w takim przypadku spowodować wyświetlenie ostrzeżenia w stylu:
"comparison is always false due to limited range of data type". Opcja ta jest też zawarta w zestawie opcji -Wextra.

EDIT:
Jeszcze tylko małe sprostowanie:
skalarro napisał(a):
a program ochoczo będzie sprawdzał warunek za każdym obiegiem

W tym przypadku nie będzie. Kod dokonujący porównania zostanie zoptymalizowany nawet przy wyłączonej optymalizacji. Tak samo nie zostanie w ogóle wygenerowany kod instrukcji wykonywanych w przypadku spełnienia warunku. Kompilator po prostu uzna, że sprawdzenie warunku zawsze zwróci fałsz.

Warunek będzie za to sprawdzany mimo bezsensownego porównania w przypadku porównania dwóch zmiennych o różnych typach, przykładowo:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Nastąpi tutaj promocja zmiennej zmienna do int, więc porównywane będą wartości 16-bitowe. W tej sytuacji wiadomo, że nie istnieje taka wartość zmiennej zmienna_int dla której porównanie mogłoby zwrócić prawdę (chyba, że wynik dodawania przekroczy zakres zmiennej 16-bitowej bez znaku), jednak w tym przypadku sprawdzanie warunku będzie się odbywać za każdym razem (praktycznie za każdym razem zwracając fałsz) i w dodatku żadne ostrzeżenie nie zostanie wygenerowane.

Innymi słowami i tak trzeba się pilnować ;)


Autor postu otrzymał pochwałę


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

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 3 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:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO