keil raz jeszcze...

witam ponownie... Znowu zatrzymalem sie na jakiejs drobnostce. Chcialem zrobic komunikacje szeregowa miedzy procesorami. W zmiennej typu char znak mam przechowany bajt danych, ktory chce wyslac szeregowo. Wszystko jest ok, tylko nie potrafie "rozebrac" bajtu na bity... Chce to zrobic iloczynem logicznym, mam ksiazke do ansi c i tam jest napisane ze wynikiem operacji bajt & bajt = true/false, tak tez napisalem kawalek kodu (do zobaczenia nizej), podczas uruchomienia debuger'a wyszlo na to ze jezeli w znak mam np. 64 (dziesietnie) i wykonam operacje znak & 64 to w wyniku otrzymam 64 (0x0040). I jak to interpretowac? dlazcego wynikiem nie jest 1? Jak poprawnie to napisac?

PS. Zmodyfikowalem program jeszcze tak: if (znak & 64 == 64){ ... ale rowniez nie dziala to prawidlowo. i w wyniku dzialania programu sa same zera nn1=0, nn2=0, nn3=0.

pozdrawiam, Bartek.

//przyklad programu fragment unsigned char znak; znak = 0x0040;

if( znak & 128 == 1 ){ data_out = 1; puts("nn1 = 1"); } else { data_out = 0; puts("nn1 = 0"); }

data_clk = 0; while(data_in == 1) {} data_clk = 1; //2

if( znak & 64 == 1){ data_out = 1; puts("nn2 = 1"); } else { data_out = 0; puts("nn2 = 0"); }

data_clk = 0; while(data_in == 1) {} data_clk = 1;

//3 if(znak & 32 == 1){ data_out = 1; puts("nn3 = 1"); } else { data_out = 0; puts("nn3 = 0"); }

Reply to
news.onet.pl
Loading thread data ...

Normalnie - napisanie "&" to jest zwykla operacja logicznego iloczynu i poprawnym wynikiem 64 & 64 jest oczywiscie 64. Jezeli chcesz cos sprawdzic przy pomocy instrukcji if (albo dowolnej innej sprawdzajacej warunek, np. na koncu petli while) - to wystarczy rozroznienie wartosci zerowej (FALSE) i niezerowej (TRUE). Krotki przyklad:

char znak = 64;

if (znak & 64) { // to jest true } else { // to jest false }

Jezeli chcesz sprawdzic, czy bit n jest zapalony, wygodniej napisac: if (znak & (1<<n)) a jezeli sprawdzasz, czy jest zgaszony: if (!(znak & (1<<n))) i juz.

Podobnie gdy w zmiennej znak chcesz zapalic bit n: znak |= (1<<n); lub go zgasic: znak &= ~(1<<n);

To co napisalem powyzej dotyczy kazdego kompilatora C na dowolna platforme, nie tylko Keila.

Reply to
Adam Dybkowski
Reply to
Bartosz Waleska
</ciach>

juz wyjasnil p. Adam Dybkowski. dzieki.

Reply to
Bartosz Waleska

W praktyce programujac w C znacznie lepiej jest pozamykac te operacje w makrach, bo w dluzszym kodzie latwo o pomylke, np. zapomni sie napisania tyldy. A w przypadku np. BSET(x,n), BCLR(x,n) i BTST(x,n) taka mozliwosc nie zachodzi.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Albo ksiazka klamie, albo Ty zaniedbales kontekst. :-) x & y to jest operacja na wektorze bitowym (w szczegolnosci na znaku) i jej wynikiem jest rowniez wektor bitowy, stad trudno przypuszczac, by mogl sie on rownac true albo false. Wartosc booleowska zwraca operator &&, ale to tez _nie jest_ to, o co Ci chodzi.

Jako brak bledu w ALU procesorka. ;-)

if (znak & 0x40) {

data_out = 1; puts("nn1 = 1");

} else {

data_out = 0; puts("nn1 = 0"); }

Dziala zupelnie prawidlowo, tylko nie w sposob, ktorego oczekujesz. ;-) Popatrz sobie na gramatyke C: multiplicative_operator jest umieszczony ponad equality_operator, wiec kompilator rozbierze ten napis jako "znak & (64==64)" zamiast "(znak & 64) == 64". 64==64 jest prawda, wiec C przeksztalci to na 1, co w efekcie da "znak & 1". Tak, w tym miejscu mozesz podziekowac panom K&R za wprowadzenie automatycznych konwersji typow, promocji i dziwnego priorytetu operatororow -- oto efekty. Uprzedzam, ze to nie ostatnia bzdura, ktora zaskoczy Cie C. BTW, tej czesci ") == 64" nie musisz dopisywac, w porownaniach C samo nieproszone przeksztalca wartosci niezerowe na true i zero na false, NULL na 0 i 0 na NULL itd. zamiast zwrocic blad "type mismatch", wiec z bolem serca mozna z tego skorzystac skracajac nieco kod zrodlowy.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Zazwyczaj do komunikacji uzywasz jakiegos interfejsu szeregowego, nie trzeba "rozbierac" bajtu programowo.

A powinno - znak nie jest przypadkiem 0 ?

tego radze unikac. Nie wiadomo czy kompilator obliczy to jako 128 czy -128. [a 1 to na pewno nie wyjdzie !]

Mozesz natomiast zapisac if (znak & 128)

Jesli wynik jest niezerowy - C uznaje to za "true".

to sie tez zazwyczaj w petli daje i przesuwanie wykorzystuje:

for (i=0;i<8;i++) { if (znak & 128) [....]

znak <<= 1 }

Reply to
J.F.

Oczywiście, zgadzam się w całej rozciągłości.

BTW: Ostatnio spotkałem się z ciekawym błędem (którego kompilator C, mając pełną rację, nie zauważył), powodującym niezłe zamieszanie. Kumpel napisał:

a=+5;

zamiast

a+=5;

Patrząc na kod, ciężko to zauważyć, a wynik jest do przewidzenia. Z drugiej strony to ciekawe, że można sobie napisać tak po prostu stałą +5 i już. Im mniejszy błąd tym dłużej się go tropi. :-)

Reply to
Adam Dybkowski

Podobne ale równie wnerwiające :) : port=!port; // zmiana stanu portu port!=port; // skompiluje się ale...

W.

Reply to
Wojt

W tym, ze wektor bitowy to zupelnie inny typ niz jego skladowa i nie mozna wprost dokonac unifikacji obu typow. Tak samo jest np. w przypadku zbioru jednoelementowego. Jest jasne, ze _nie_ jest on rownowazny swojemu elementowi, {a} != a. Jest to po prostu niedopuszczalne na poziomie formalnym.

Ale to wymaga niejawnej konwersji typu {0,1}^n -> bool. Porzadne jezyki programowania nie zezwalaja na automatyczna zmiene typu argumentu i zglaszaja to uzytkownikowi jako blad systemu typow, wymuszajac jawne rzutowanie, a w C nawet nie dostaniesz informacji, ze cos jest nie tak. Zreszta takich kwiatkow jest wiecej.

Sa ludzie, ktorzy narzekaja, a ja sie do nich zaliczam, bo na pierwszym miejscu stawiam sobie elegancje i spojnosc formalna jezyka. Przyznaje, ze C jest wygodnym narzedziem, uzywam go i bede uzywal oraz uczyl tego jezyka studentow informatyki, ale nie zmienia to faktu, ze od strony formalnej to jest potworek.

A to jest niezgodnosc ze standardem, czyli blad kompilatora.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.