Skocz do zawartości
SACZI

typ znakowy, a całkowity

Rekomendowane odpowiedzi

Pytanie właściwie z podstaw C.

Deklaruję zmienną, jest ona typu char, czyli 8 - bit.

Kiedy kompilator interpretuje typ char jako zmienną typu znakowego, a kiedy jako liczby całkowite (0 - 255).

Czy ten problem rozwiazuje typ signed char ??

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Wiesz co? Wlasciwie nie wiem jak jest w specyfikacji ale:

Zlukaj to.

Poprostu sprawdz jak jest w Twoim kompilatorze puszczajac petle i wypisujac wartosc zmiennej na ekran, nie trzeba wszystkiego zawsze pamietac.

Aha i jeszcze z podstaw: sa typy signed char, unsigned char i char (ktory sprawdz), unsigned char to 0-255 a signed char to -128-127 (czy jakos tak).

W sumie odpowiedz bardzo nie rzeczowa i mozna bylo odpowiedziec prosciej ale jesli zalezy Ci na czasie to moze pomoze...

 

update: Za szybko pisze chyba... Generalnie jest tak ze ujemne poznajesz po najstarszym bicie (1 jak ujemna a 0 jak dodatnia) tak wiec unsigned powyzej 128 beda mialy ustawiony bit jak i signed powyzej 0 maja ustawiony, dlatego z wyswietlaniem na ekran bedzie ten problem ze poprostu zalezy jako co to wyswietlisz. Tak czy siak nie jestem juz nawet pewien czy bzdur nie pisze wiec koncze, niech odpowie ktos kto wie a Ty poprostu posprawdzaj.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

W programie wyglada to w ten sposób:

#define cbInQueue  4096     //rozmiar bufora danych wejściowych...TForm1 *Form1;char  Bufor_WE[cbInQueue];  // bufor danych wejściowych
Zadaniem programu jest odbieranie danych z portu RS232c i następnie zapisywanie ich do pliku po lekkiej "obróbce".

Do bufora przychodzą wartości typu: 2567, 2209 itd, czyli całkowite 2 x 8 - bitów.

Program obecnie interpretuje te "liczby" jako kody ASCII, a ja potrzebuję, żeby zinterpretował mi je jako LICZBY.

Czyli: 2567 = 1010 00000111 (idzie liczba 12 - bitowa).

Jeżeli zinterpretyuje je jako liczbę, to OK, ale jak kod ASCI, to klapa, bo w chyba 99% nie ma takich kodów znaków i dostaję jakąś chińszczyznę.

 

Obawiam się, że jednak typ unsigned char dostarczy dodatkowo 128 DEC (*), z których korzystają rozszerzone kody ASCII. Przy próbie podstawienia jakiegokolwiek typu int, kompilator wywala mi błędy: Can't convert typ; Type mismatch.

 

Kompilator to C++ Builder.

Wg Daniluka:

signed char - typ integer, rozmiar 8 bit

unsigned char - typ integer, rozmiar 8 bit, bez znaku

char - 1 znak ANSI, character, rozmiar 8 bit

char - character, rozmiar 8 bit, bez znaku.

 

Wg C++ Builder Dla Każdego:

char 8 bit -128 do 127

unsigned char 0 do 255

 

W sumie wszystko jesna, ale jednak czegoś nie wiem ...

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeżeli chcesz operować na liczbach 0-255 to zadeklaruj zmienną jako unsigned char. Dla kompilatora char jest cały czas typem liczbowym. A to że dostajesz znaki ASCII to znaczy że używasz do wyświetlania wyników jakiejś funkcji, które interpretuje to jako znaki. Wystarczy więc albo użyć innej funkcji, albo rzutować typ char np na short. Przykładowo:

char zmienna=97;cout<<zmienna; //zostanie wypisana literka acout<<(short)zmienna; //zostanie wypisane 97

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ja mysle ze problem jest inny i wynikl z jakiegos niezrozumienia, jakiego nie wiem wiec napisze pare roznych rzeczy.

 

Czy uzywasz char czy int czy long dla kompilatora sa to zawsze typy liczbowe (tak jak pisze Megabyte), typ char sie poprostu glupio nazywa, tak naprawde jest to zwykly typ liczbowy tak jak int majacy "w sobie" miejsca 1 bajt. Dla przykladu analogiczny typ w pascalu nazywa sie byte co jest sporo zdrowsze moim zdaniem...

Tak wiec jesli operujesz na liczbach o wartosciach ktorych nie da sie zapisac na jednym bajcie uzywasz wiekszego typu, inaczej sie nie da. Gdy odczytujesz te swoje dane do bufora w ktorym element ma jeden bajt a liczby ktore chcesz wlozyc sie na bajcie nie zmieszcza nastapi jakas konwersja przy przypisaniu (zalezna od kompilatora czy systemu operacyjnego np w zaleznosci od tego jak to robisz) i tak czy siak zostana zapisane liczby 0-255 albo -128-127. Gdy Ty wpisywales tam 2200 to przy wyswietlaniu nie bylo tego problemu ze 2200 jest z poza asci, Ty wyswietlales powiedzmy asci 34 bo zalozmy ze taka liczbe dalo ostatnie 8 bitow liczby 2200 (pisze bzdure ale nie chce mi sie liczyc, to i tak jedno z mozliwych wynikow tylko).

Podsumowujac, jesli uzywasz liczb wiekszych niz 255 to musisz uzywac typu ktory je "zmiesci". Jako ze uzywasz np 2000 polecam int ktory miesci 16 bitow (czli 0-64000 albo -32000 do 32000). Mowiac krotko zmien typ tablicy bufor_WE na int :)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

zmien typ tablicy bufor_WE na int

Nie da rady: błędy kompilacji (Cannot convert 'char' to 'short int'; Type mismatch in parameter 'parameter'), próbowałem to.

 

Nie mogę zmienić typu na 16 bit, bo jest on wykorzystywany w dalszych funkcjach.

Liczby, które odbieram są spoko. W dalszej części programu "składam" je w 16 (12) bitowe.

Dla kompilatora char jest cały czas typem liczbowym.

To mnie własnie najbardziej z tego wszystkiego cieszy. Wiedziałem to, ale z tego wszystkiego juz zgłupiałem i chciałem sie upewnić.

Korzystam również z kompilatora Keil C. W nim char jest po prostu typem liczbowym. Na procesorach '51 za bardzo sie nie operuje na znakach (literach) i wszystko jest tam przedstawiane jako liczby.

 

A to że dostajesz znaki ASCII to znaczy że używasz do wyświetlania wyników jakiejś funkcji, które interpretuje to jako znaki.

Form1->RichEdit1->Text =IntToStr(Bufor_WE);
Dokładnie jest tak jak mówisz. Jednak zastanawia mnie jeden fakt. Uzywając powyższej konstrukcji mam krzaki, gdzy zapiszę:

Form1->RichEdit1->Text = Bufor_WE;
odbieram ciągle liczbe 1.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

zmien typ tablicy bufor_WE na int

Nie da rady: błędy kompilacji (Cannot convert 'char' to 'short int'; Type mismatch in parameter 'parameter'), próbowałem to.
Dziwne, znaczy ze starasz sie wrzucic do tablicy chary z tego Twojego tajemniczego czegos. W jaki sposob na tych charach przechowujesz 2000? No chyba ze liczby sa podzielone albo wresz leca w bitach i sobie sklejasz jak chcesz co by wynikalo z tego ponizej... Napisz moze wiecej o co w ogole chodzi tzn jakie faktycznie liczby z czego i w jakim formacie i typie leca i do czego chcesz je wlozyc. Generalnie dalej nie wiem czy w ogole rozumiesz podstawy typow... Aha, jeszcze jest rzutowanie ale to juz napewno musisz wiedziec co robisz...

przyklad rzutowania

int i;char c;i = (int)c;

Nie mogę zmienić typu na 16 bit, bo jest on wykorzystywany w dalszych funkcjach.

Liczby, które odbieram są spoko. W dalszej części programu "składam" je w 16 (12) bitowe.

Mhm... Czyli odbierasz bajty i z dwoch skladasz te swoja liczbe 12 bitowa.

 

Dla kompilatora char jest cały czas typem liczbowym.

To mnie własnie najbardziej z tego wszystkiego cieszy. Wiedziałem to, ale z tego wszystkiego juz zgłupiałem i chciałem sie upewnić.

Korzystam również z kompilatora Keil C. W nim char jest po prostu typem liczbowym. Na procesorach '51 za bardzo sie nie operuje na znakach (literach) i wszystko jest tam przedstawiane jako liczby.

Uzywaj unsigned juz prawie napewno.

 

A to że dostajesz znaki ASCII to znaczy że używasz do wyświetlania wyników jakiejś funkcji, które interpretuje to jako znaki.

Form1->RichEdit1->Text =IntToStr(Bufor_WE);
Dokładnie jest tak jak mówisz. Jednak zastanawia mnie jeden fakt. Uzywając powyższej konstrukcji mam krzaki, gdzy zapiszę:

Form1->RichEdit1->Text = Bufor_WE;
odbieram ciągle liczbe 1.
No tu mam cwieka bo kontrolek z visuala nie znam (czy tam z czego to jest). Co do pierwszego to przeczytaj czy inttostr bierze char na wejsciu bez problemu, szczegolnie gdy jest signed, jesli nie to zrzutuj na int czyli (int)(Bufor_WE).

Co do drugiego to nie wiem, pytanie jak reaguje kontrolka Text na operacje przypisania.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

W jaki sposob na tych charach przechowujesz 2000? No chyba ze liczby sa podzielone albo wresz leca w bitach i sobie sklejasz jak chcesz co by wynikalo z tego ponizej... Napisz moze wiecej o co w ogole chodzi tzn jakie faktycznie liczby z czego i w jakim formacie i typie leca i do czego chcesz je wlozyc.

Odbieram na RS232 dane w formacie:

 

|char|char|char|char|**|; ** znacznik końca "ramki" 0x0D

 

gdzie char to pojedyncza ramka transmisji szeregowej (8, N, 1), wysyłane liczby, od prawej odpowiednio starsza i młodsza część bajtu. Taki format ramki podyktowany jest koniecznością zapisania odebranych danych na dysku w dwóch kolumnach.

Liczby 12 bitowe biorą się ze złozenia starszego i młodszego bajtu:

short conv_val;unsigned char zmH, zmL;conv_val = zmL | ((zmH & 0x0F) << 8);

Problem mój polega na odpowiedniej interpretracji odbieranych danych. Program obecnie interpretuje te dane jako kody ASCII i stąd te krzaki. Chce go przepisać w taki sposób, aby dane interpretował jako liczby i stad moje pytania.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Form1->RichEdit1->Text =IntToStr(Bufor_WE);
Dokładnie jest tak jak mówisz. Jednak zastanawia mnie jeden fakt. Uzywając powyższej konstrukcji mam krzaki
Jeżeli Bufor_WE jest tablicą charów to ta instrukcja nie jest poprawna. Musisz przekonwertować każda liczbe osobno np tak:

 

for (int i=0; i<cbInQueue; i++)  RichEdit1->Lines->Add(IntToStr(Bufor_WE[i]));

gdzy zapiszę:

Form1->RichEdit1->Text = Bufor_WE;
odbieram ciągle liczbe 1.
Ta instrukcja jest poprawna jednak nie robi to czego oczekujesz. Po prostu interpetuje cały bufor jako napis. Zapewne drugą wartością w tablicy jest 0 a pierwszą kod ASCII odpowiadający liczbie 1

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...