logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak poprawić kod konwersji binarno-heksadecymalno-ascii w C?

trol.six 13 Maj 2018 15:44 2247 52
Najlepsze odpowiedzi

Jak poprawić w C kod, który konwertuje liczby binarne na ASCII-hex i z powrotem, żeby był czytelniejszy, poprawniejszy i szybszy?

Najlepiej uprościć API, użyć jawnych typów o znanym rozmiarze, wydzielić wspólną funkcję zamieniającą tetradę na cyfrę hex i skanować liczby od początku, a nie od końca [#17218708][#17219824] Jeśli argument nie jest modyfikowany, oznacz go `const`; nie przekazuj `void *`, jeśli funkcja i tak operuje na `unsigned char *`, bo tracisz sprawdzanie typów przez kompilator [#17219824] Warto też usunąć zbędne `else`, `continue` i `break`, bo tylko zaciemniają kod; prostszy przepływ sterowania zwykle daje mniej skoków i bywa szybszy [#17218708][#17219824] Do zamiany nibble→hex można użyć krótkiego helpera albo lookupu z napisem `"0123456789ABCDEF"`, a jeśli zależy Ci na rozmiarze i prędkości, porównaj obie wersje na docelowych platformach, bo wyniki zależą od kompilatora i opcji optymalizacji [#17219824] Warto też pamiętać, że bajty dowolnego obiektu można oglądać jako `char*`, o ile nie wychodzi się poza bufor, więc samo rzutowanie nie jest z definicji błędem [#17220919]
  • #1 17218669
    trol.six
    Poziom 31  
    Posty: 1650
    Pomógł: 151
    Ocena: 381
    Z myślą o chudszej obsłudze formatów i innych myślach i bezmyśleniach, napisałem kod do konwersji liczb binarnych na hexadecymanalny ciąg znaków kodowanych w ascii. Oraz kod konwertujący w drugą stronę czyli czytający pojedynczą liczbę, oraz czytający kolejne wyrazy z ciągu i zamieniający na liczbę binarną.

    W pliku h są makra aby używać tych funkcji czytelniej.
    zamiast:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    piszemy:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Wszelkie uwagi odnośnie kodu, błędy, choćby kwestia opcji optymalizującej ;) na rozmiar liczby binarnej, co można zrobić inaczej, mile widziane.

    Liczby wczytywane są od części mniej znaczącej. Ma to znacznie w przypadku nierównych wzajemnie sobie kodowań.
    Czyli dla hex "0000000001" będzie 1
    ale dla hex "0000010000"
    dla liczby 16 bitowej będzie 0
    dla liczby 32 bitowej będzie 65536

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    całość:
    https://github.com/trolsix/binhexconv

    lub załączniki pliki c i h.
    .
    Załączniki:
    • binhexconv.zip (2.57 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #2 17218708
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Bardzo fajny przykład dydaktyczny z serii "jak nie należy pisać programów". ;)

    Typy... od 19 lat mamy w C typy o jawnych rozmiarach - uint8_t, int16_t itd..
    Dobra zasada - jeśli coś nie może być ujemne - powinno być typu bez znaku. Czy rozmiar danej może byś ujemny?
    Dekompozycja na procedury - dwa razy pod rząd mamy ten sam paskudny kod zamiany tetrady na cyfrę hex.
    Co powiesz na:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    If () bez else jest czytelniejszy i szybszy - u Ciebie wszędzie mamy else przy obróbce cyfr szesnastkowych.

    Po if, for, while stawia się spację, żeby nie myliło się to z wywołaniem funkcji.
    Makra powinny mieć nazwy z wielkich liter.
    Nazwy zmiennych powinny być znaczące - u Ciebie mamy tmp, tmp1, tmp2, tmp3.
    Błędne, zaciemniające kod, zbędne użycie continue i break w pętli for.
  • #3 17218726
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    BlueDraco napisał:
    Dobra zasada - jeśli coś nie może być ujemne - powinno być typu bez znaku. Czy rozmiar danej może byś ujemny?

    Z drugiej strony, na przykład zasady google mówią, że:

    Cytat:
    The best advice we can provide: [...] try to avoid unsigned types (except for representing bitfields or modular arithmetic). Do not use an unsigned type merely to assert that a variable is non-negative.
  • #4 17218790
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    I pewnie dlatego od wieków istnieją w C takie byty jak size_t... ;)
  • #5 17218795
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    BlueDraco napisał:
    I pewnie dlatego od wieków istnieją w C takie byty jak size_t... ;)


    Cytat:
    Because of historical accident, the standard also uses unsigned integers to represent the size of containers - many members of the standards body believe this to be a mistake, but it is effectively impossible to fix at this point.


    I moja opinia jest identyczna, chociażby dlatego że arytmetyka na size_t może prowadzić do dziwnych błędów, ot odejmij większy od mniejszego no i masz sporo większy. ;)
  • #6 17218929
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    To o tyle ciekawe, że w kilku coding standards wisi zasada, że jeśli coś jest nieujemne, to ma być w typie bez znaku.
  • #7 17218957
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    Cóż, tak jak z niektórymi ich pomysłami to mógłbym się spierać, tak z tym, z uwagi na upośledzoną arytmetykę na unsigned... no przemawia to do mnie. A że w różnych "coding standards" jest inaczej, a to na pewno, jestem pewien że w nich jest wiele przeciwstawnych rzeczy, zależnie od tego co autorzy preferują. ;)
  • #8 17219081
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Nie wiem, o co chodzi z tym upośledzeniem. Równie dobrze możesz powiedzieć, że "upośledzona" jest na signed, bo jak dodasz 100 i 100 to wyjdzie bajt o wartości ujemnej.
  • #9 17219127
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    A to jeszcze zależy, w wypadku używania CPU który ma "saturation arithmetic", z tego działania możesz dostać 127. No ale, jest upośledzona bo nie zachowuje się jak tego można by oczekiwać po integerze, co do błędów związanych z przepełnieniem dodaje kolejne. No ale, jak pisałem wyżej, to jednak kwestia tego co lubią autorzy. Tym niemniej, o ile googlowy tekst jest poprawny, to typy unsigned zostały oblyślone głownie do pól bitowych i arytmetyki modulo, a ludzie co wymyślili aby size_t był unsigned, by się z tego wycofali o ile by mogli. Więc może coś w tym jest...
  • #10 17219527
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    No faktycznie, możliwość zaalokowania bufora o ujemnym rozmiarzy byłaby bardzo cenna. Taki bufor jest niezbędny np. przy odbiorze niepotrzebnych danych.
  • #11 17219539
    Konto nie istnieje
    Konto nie istnieje  
  • #12 17219687
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    BlueDraco napisał:
    No faktycznie, możliwość zaalokowania bufora o ujemnym rozmiarzy byłaby bardzo cenna. Taki bufor jest niezbędny np. przy odbiorze niepotrzebnych danych.
    Przy czym bufora o ujemnym rozmiarze zaalokować się nie da, a bardzo duży o dodatnim akurat może się udać (; I tak oto używając arytmetyki "signed" aplikacja się wyłoży, a przy "unsigned" może kontynuować w "uszkodoznym" stanie dalej... to się liczy jako trudno diagnozowalny błąd? (;

    powrotnik napisał:
    @Sareph A na pewno size_t ze znakiem powodowało by że trzeba by używać dłuższego typu - co na pewno jest świetnym rozwiązaniem (np arytmetyka 32 bitowa dla 8 bitowców)
    Aha, jasne. Nawet pomijając to, że mowa o systemach 32bit, bo na 8 bit AVR to akurat uint8_t i zabawy z nim mogą mieć sens, chociażby dlatego, że size_t jest 16 bit (; To... Często widujesz tablice, których liczba elementów idzie w miliardy na 32bit systemie? Albo często alokujesz ciągłe bloki >32k na AVR? Który i tak ma często (zawsze?) dużo mniej wbudowanego SRAM.

    Żeby było jeszcze zabawniej, standardowa aplikacja 32bit na Windowsie (także x64) nie może zaalokowac więcej niż 2GiB pamięci. Na Linuksie jest podobnie. Ale nawet jak dostaniesz te 3GiB (lub 4 na 64bit systemie) do dyspozycji to powodzenia w alokowaniu ciągłego obszaru takiego rozmiaru. A jakbyś już wpadł na pomysł "hohooh, a ja użyje połączonej listy, nie potrzebuje ciągłego bloku!", to że potrzebujesz na to minimum 5B na element, to daje maks 644245094 elementów i spokojnie mieści się w zakresie signed. Także pytanie, jakie Ty dane chcesz przechowywać aby pochłonąć całą dostępną pamięć za jednym razem? (;

    powrotnik napisał:
    Te dywagacje google są dla mnie nieco szokujące - szczególnie uwaga aby nie sprawdzać czy przypadkiem liczba bez znaku nie ma znaku. Czyżby takie mieli kadry?
    A może czas opanować lepiej angielski i zrozumieć co tam jest faktycznie napisane? (;
  • #13 17219713
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Pomysł, że by zabezpieczać się przed przekroczeniem zakresu liczb bez znaku pprzez wykrywanie znaku dla mnie wygląda jak urojenia przedszkolaka. Każda reprezentacja ma jakiś zakres i w każdej programista odpowiada za jego dobór - i nieprzekraczanie. Suma dwóch dodatnich liczb dająca wynik ujemny jest na moje oko bardziej bezsensowna, niż "zbyt duża" liczba dodatnia albo błędny wynik odejmowania dwch liczb nieujemnych, o których wiadomo, że pierwsza powinny być większa od drugiej (a z powodu błędu programisty nie jest).

    Z drugiej strony rekomendacja programistów firmy X wcale mnie nie dziwi, bo oglądając jakość "profesjonalnego" kodu źródłowego pewnej znanej, szanowanej i powszechnie używanej biblioteki wyzbyłem się złudzeń co do profesjonalizmu jej twórców.

    Arytmetyka z nasyceniem - wiemy, że dzwonią, ale nie wiemy, w którym kościele. Ok, jest i jest używana, ale nigdy w typach podstawowych, bo podstawowe operacje w programych muszą "zawijać" zakresy. żaden typ nasycany nie zastąpi typu "zawijanego". Typy nasycane są potrzebne np. jako typy danych w przetwarzaniu sygnałów, ale nie do liczenia zajętości pamięci.
  • #14 17219718
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    BlueDraco napisał:
    Arytmetyka z nasyceniem - wiemy, że dzwonią, ale nie wiemy, w którym kościele.
    Wiesz, ja z całkowita premedytacją wstawiłem tam słowo *możesz* (bo to słowo, to raczej nie oznacza, ze przy używaniu instrukcji arytmetyki nasyceniowej ALU może się pomylić). I ta uwaga to raczej jako ciekawostka była.

    No ale. Jak na przykładzie, który sam dałeś widać, to chodzi o wykrywanie nietypowych sytuacji, w których ktoś zapomniał dać if()a. A nie o to, że się kodu z arytmetyka "unsigned" nie da napisać, bo się da.
  • #15 17219747
    trol.six
    Poziom 31  
    Posty: 1650
    Pomógł: 151
    Ocena: 381
    BlueDraco napisał:
    Typy... od 19 lat mamy w C typy o jawnych rozmiarach - uint8_t, int16_t itd..

    Też się nad tym zastanawiałem, jednakże jeśli ktoś nie trafi na kompilator gdzie typ unsigned char ma inną wielkość, to nie chciałem ograniczać rozmiaru danych. Przecież nawet same wskaźniki są różne w zależności od platformy.

    BlueDraco napisał:
    Dobra zasada - jeśli coś nie może być ujemne - powinno być typu bez znaku

    Dobrze że zwróciłeś na to uwagę. W plikach *h tak jest,
    natomiast źle przekopiowałem jedną funkcje po zmianach i wyszedł błąd.

    BlueDraco napisał:
    Co powiesz na:

    Kod: c [rozwiń] [zaznacz wszystko]

    static inline char hexdigit(uint8_t v)
    {
    return "0123456789ABCDEF"[v & 0xf];
    }

    Ponieważ odczyt z tablicy w maluczkich uC zajmuje "dużo" flash i czasu też, dlatego nie ma odczytu z żadnych tablic. A w tych gdzie ciąg ląduje w ram, zużywa ją niepotrzebnie.

    BlueDraco napisał:
    If () bez else jest czytelniejszy i szybszy - u Ciebie wszędzie mamy else przy obróbce cyfr szesnastkowych.

    W tym przypadku, wcale że nie, z else wprawdzie kod jest dłuższy, ale nie trzeba sprawdzać kolejnych warunków, co sprawia że jest szybszy. Być może gdyby warunków if byłoby mniej, albo architektura uC inna, sytuacja byłaby jak piszesz.

    BlueDraco napisał:
    Makra powinny mieć nazwy z wielkich liter.

    Przecież są z wielkich.

    BlueDraco napisał:
    Nazwy zmiennych powinny być znaczące - u Ciebie mamy tmp, tmp1, tmp2, tmp3.

    Podczas pisania nie miałem pomysłu jak je nazwać inaczej. ;)

    BlueDraco napisał:
    Błędne, zaciemniające kod, zbędne użycie continue i break w pętli for.

    Dlaczego błędne? Brzydkie owszem, troszkę namieszałem.
    Miałem ochotę zastąpić je wszystkie czymś zgrabnym. Ale coś wena twórcza słaba.

    BlueDraco napisał:
    To o tyle ciekawe, że w kilku coding standards wisi zasada, że jeśli coś jest nieujemne, to ma być w typie bez znaku.

    Ja widze że jest jeden sens używania liczb ujemnych w takich przypadkach. Jeśli funkcja zwraca liczbę dodatnią to jest dobrze, a jak ujemną to oznacza że jest błąd. Z tym że operacje na takich liczbach powinny być już na typie unsigned.

    Ale nabazgrałem coś takiego.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #16 17219824
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    trol.six napisał:
    Ponieważ odczyt z tablicy w maluczkich uC zajmuje "dużo" flash i czasu też, dlatego nie ma odczytu z żadnych tablic. A w tych gdzie ciąg ląduje w ram, zużywa ją niepotrzebnie.

    Na szczęście choinka if then else zajmuje zero bajtów i zero instrukcji oraz wykonuje się w ujemnym czasie. Proponuję najpierw sprawdzić obie wersje na min. 2 platformach, a potem wyciągać wnioski nt. zajętości pamięci.
    Można też:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    albo
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Jeśli procedura nie zmienia argumentu przekazanego przez wskaźnik, to powinien mieć on atrybut const. W Twoich funkcjach const nie występuje.
    Przekazujesz do funkcji argument typu void *, po czym reinterpretujesz go jako unsigned char * co jest b. dobrym źródłem błędów.
    Liczby zawsze skanuje się od przodu, a nie od tyłu:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    - to całe skanowanie liczby hex z łańcucha znaków
    Wreszcie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Można bez else?
    Praa domowa: porównaj długość kodu tej funkcji w wersji z else i bez.

    Cytat:

    W tym przypadku, wcale że nie, z else wprawdzie kod jest dłuższy, ale nie trzeba sprawdzać kolejnych warunków, co sprawia że jest szybszy. Być może gdyby warunków if byłoby mniej, albo architektura uC inna, sytuacja byłaby jak piszesz.


    Warunków z else czy bez tyle samo, skoków mniej - więc wykonanie sporo szybsze.

    Błędne algorytmy (skanowanie od tyłu) i błędna dekompozycja (to samo dla dwóch cyfr w pętli) powodują kilkukrotne wydłużenie kodu i znaczne jego spowolnienie.
  • #17 17219869
    Konto nie istnieje
    Konto nie istnieje  
  • #18 17219887
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    powrotnik napisał:
    To nie jest prawda objawiona tylko czasami pojawiające się w dyskusjach o C++ zdanie jednego gościa, powtarzane czasem przez innych dyskutantów.
    Źródło?

    powrotnik napisał:
    Twoje dywagacje nt wielkości bloków pamięci itd itd są całkowicie bez sensu bo standard jest wyabstrahowany od konkretnej platformy.
    Standard jako taki, tak. Ale tu mowa o konkretnych implementacjach. Wiec pokaż mi przykład na jakiejś platformie (z którymi to C jest związany jak cholera, to nie java), kiedy zmiana size_t z unsigned na signed, wymusiła by powiększenie typów danych, bo coś (nie wyimaginowanego) się w nim nie zmieści.

    powrotnik napisał:
    A wpadłeś na pomysł że może sam po prostu nie rozumiesz tego co czytasz? - weż słownik przetłumacz sobie słowo po słowie.
    Nawet automatyczny tłumacz ma na ten temat zdanie odmienne od Twojego. Ale spoko, możesz wierzyć w co chcesz. ;)

    "Do not use an unsigned type merely to assert that a variable is non-negative." -> "Nie używaj bez-znakowych typów tylko aby jedynie podkreślić/zaznaczyć, że zmienna nie może być ujemna".
  • Pomocny post
    #19 17219937
    Konto nie istnieje
    Konto nie istnieje  
  • #20 17219947
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    powrotnik napisał:
    @Sareph Jak się nie ma argumentu to się pisze takie posty.

    Znaczy jakie? Proszenie o źródło danych, czy o "real-life" example, albo poprawne przetłumaczenie zdania w którym źle rozumiałeś znaczenie słowa "assert", jest przepraszam bardzo, czym? Atakiem ad-personam?
  • #21 17219954
    Konto nie istnieje
    Konto nie istnieje  
  • #22 17219975
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    powrotnik napisał:
    Naprawdę uważasz że ktoś tworzący Standard wybrał by typ, który powoduje UB w przypadkach brzegowych. Przecież to absurd.
    O jasne, nie trudno wyobrazić sobie sytuacje kiedy z jakichś powodów wybrano takie a nie inne rozwiązanie, bo wyglądąło dobrze na papierze a rzeczywistość pokazała, że nie był to najlepszy pomysł, no ale ze kompatybilność wsteczna...

    powrotnik napisał:
    Nie widzę ataku personalnego. Omijasz tylko argumenty, na które nie masz odpowiedzi.

    To była ironia, to raz. Dwa - robisz dokładnie to samo, więc się dostosowuje.

    powrotnik napisał:
    Pytasz o źródła. Ja podałem Ci cytaty ze standardu o liczbach ze znakiem i bez. I wytłumaczyłem dlaczego liczby ze znakiem nie mogą być size_t.
    To wspaniale, ale pytanie o źródło nie odnosiło się do tego co podałeś. Pytałem o źródło informacji, że:

    Cytat:
    tylko czasami pojawiające się w dyskusjach o C++ zdanie jednego gościa, powtarzane czasem przez innych dyskutantów.


    Więc jak to było zdanie jednego gościa... ot z ciekawości chce wiedzieć którego, i na podstawie tego podjąć decyzje czy się z nim zgadzam, chociażby był jedynie jedyny czy jego argumentacja była nieprawidłowa.

    To wycofujesz się z "szczególnie uwaga aby nie sprawdzać czy przypadkiem liczba bez znaku nie ma znaku" czy, dalej twierdzisz że w tym zdaniu o to chodzi? (; Bo ja się jednak będę upierał, że wydźwięk jest inny.

    A co do UB w indeksach, nie ma typu danych który gwarantuje brak UB w jakimkolwiek odwołaniu do pamięci, zawsze możesz wyjść poza zakres.
  • Pomocny post
    #23 17219989
    simw
    Poziom 27  
    Posty: 756
    Pomógł: 94
    Ocena: 286
    BlueDraco napisał:

    Dobra zasada - jeśli coś nie może być ujemne - powinno być typu bez znaku. Czy rozmiar danej może byś ujemny?
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Bardzo ciekawy wątek, zmusza do myślenia, również początkującego.
    Zaciekawiło mnie zatem to co wyżej.

    Z jednej Kolega krytykuje używanie typów ze znakiem, a z drugiej proponuje typ char jako wynik działania funkcji, pomimo, że nie ma "znaków ujemnych".
    Doczytałem zatem pewien fragment z książki:
    Język C. Szkoła programowania. Wydanie VI Stephen Prata

    gdzie napisano, że typ char jest niejednoznaczny, w zależności od implementacji może być ze znakiem lub bez znaku, w gcc jest ze znakiem, a "internecie" też doczytałem, że nawet może być 16-bit:
    https://community.st.com/thread/34795-why-uint8t-instead-of-char-for-strings

    Jak dla mnie taki char wprowadza bałagan, a jego niejednoznaczność powinna go wykluczać, szczególnie z teoretycznie uniwersalnej, biblioteki.

    Można prosić o komentarz, bo dla mnie nie trzyma się to wszystko "kupy".
  • #24 17219996
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    simw napisał:
    Z jednej Kolega krytykuje używanie typów ze znakiem, a z drugiej proponuje typ char jako wynik działania funkcji, pomimo, że nie ma "znaków ujemnych".


    Nooo nie. Char nie jest od liczb w zasadzie, jest od znaków, a że ludzie lubią go wykorzystywać w innych celach to inna historia. int8_t jak już, albo int_fast8_t, zależy od sytuacji. (;
  • #25 17220006
    Konto nie istnieje
    Konto nie istnieje  
  • #26 17220011
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    powrotnik napisał:
    @Sareph Wybacz ale chyba nie wiesz co to jest UB.
    Mówimy o Undefined Behaviour? No to myślę, że wyjście poza zakres powoduje jednak UB.

    powrotnik napisał:
    Typy unsigned mają ściśle określone przez standard zachowanie w takich przypadkach - modulo 2^n. Zachowanie typu signed jest nieokreślone (mogą się zachowywać dowolnie). Indeksy ex definitione mają mieć zachowanie ściśle określone. Skreśla to liczby ze znakiem z listy możliwych typów.
    Tylko mi powiedz co za różnica, skoro i tak wyszedłeś poza zakres? To i tak bład i UB spowoduje. I co za różnica w którym punkcie (czy przy obliczeniu wskaźnika czy przy samym dostępie) skoro i tak to się skończy tak samo?

    powrotnik napisał:
    To zdanie o które pisałeś rzuciło mi się w oczy kilka razy na githubie w dyskusjach i ciągle był to ten sam użytkownik. Wygoogluj sobie i zobacz.
    A czyli w zasadzie... nie znasz źródła, ok.

    powrotnik napisał:
    Coding standard który zakłada użycie...
    Może powinniście im zwrócić uwagę, że są jak przedszkolaki? (;

    Dodano po 4 [minuty]:

    powrotnik napisał:
    int_fast8_t nie ma nic wspólnego z int8_t i może być np 64 bitowy.
    No i? Idealny typ na zmienne używane na stosie/w rejestrach. I właśnie dlatego (;
  • #27 17220038
    Konto nie istnieje
    Konto nie istnieje  
  • #28 17220046
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    I dlatego w tym zdaniu stoi "zależy od sytuacji", bo że wiedzieć co się robi to jednak zawsze wypada. (;
  • #29 17220073
    simw
    Poziom 27  
    Posty: 756
    Pomógł: 94
    Ocena: 286
    Sareph napisał:
    simw napisał:
    Z jednej Kolega krytykuje używanie typów ze znakiem, a z drugiej proponuje typ char jako wynik działania funkcji, pomimo, że nie ma "znaków ujemnych".


    Nooo nie. Char nie jest od liczb w zasadzie, jest od znaków, a że ludzie lubią go wykorzystywać w innych celach to inna historia. int8_t jak już, albo int_fast8_t, zależy od sytuacji. (;

    Mnie to brzmi jako jakiś ciężki anachronizm.
    Z jednej strony tworzy się zasady, o dobieraniu typów do znaków, a z drugiej trzyma się kurczowo "jakiegoś char", które to chyba jest tylko po to, żeby wyróżnić operacje na znakach, a cała reszta to tylko niepotrzebne komplikacje, jak te ze zmianą zakresów w zależności od implementacji.

    Ja w swoich nieśmiałych próbach programowania znaków i stringów zawsze używam uint8_t ( mikrokontrolery 8 i 32 bit), czy takie podejście rodzi jakieś konkretne niebezpieczeństwa i problemy, czy można się tego trzymać?
  • #30 17220149
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    simw napisał:
    nie to brzmi jako jakiś ciężki anachronizm.
    Z jednej strony tworzy się zasady, o dobieraniu typów do znaków, a z drugiej trzyma się kurczowo "jakiegoś char", które to chyba jest tylko po to, żeby wyróżnić operacje na znakach, a cała reszta to tylko niepotrzebne komplikacje, jak te ze zmianą zakresów w zależności od implementacji.

    Ja w swoich nieśmiałych próbach programowania znaków i stringów zawsze używam uint8_t ( mikrokontrolery 8 i 32 bit), czy takie podejście rodzi jakieś konkretne niebezpieczeństwa i problemy, czy można się tego trzymać?

    Jest to błąd, ponieważ wg standardu typy "char", "unsigned char" i "signed char" to trzy różne typy, które nie są ze sobą kompatybilne. Jeśli tylko będziesz chciał użyć swojego kodu z którąś ze standardowych funkcji (printf, sprintf, strlen, strcpy, ...), to dostaniesz więc co najmniej warninga o tym że nie zgadzają się typy (w C++ dostaniesz errora).

Podsumowanie tematu

✨ W dyskusji poruszono kwestie dotyczące optymalizacji kodu konwersji binarno-heksadecymalno-ascii w języku C. Użytkownik zaprezentował swój kod, który konwertuje liczby binarne na ciągi heksadecymalne oraz odwrotnie, a także używa makr dla uproszczenia wywołań funkcji. Otrzymał liczne uwagi dotyczące użycia typów danych, dekompozycji kodu, czytelności oraz optymalizacji. Zwrócono uwagę na znaczenie używania typów o jawnych rozmiarach, takich jak uint8_t i int16_t, oraz na problemy związane z używaniem void* w kontekście typów wskaźnikowych. Dyskutowano również o wydajności różnych podejść do konwersji oraz o znaczeniu czytelności kodu w kontekście przyszłych modyfikacji.
REKLAMA