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

funkcja wyswietlajaca liczby na lcd /gcc/ rozwiazane

dturczak 01 Lis 2007 23:14 1296 7
REKLAMA
  • #1 4438400
    dturczak
    Poziom 19  
    Posty: 416
    Pomógł: 9
    Ocena: 5
    write_text("123");
    elegancko mi wyswietla te chary...
    chcialem zrobic funkcje wyswietlają dowolne liczby calkowite int:
    
    void write_int(int liczba){
    int ile;
    int pom=liczba;
    char cyfra;
    for(ile=1;(liczba=liczba/10);ile++);
    char *znaki;
    znaki=znaki+ile+1;
    *znaki=0;
        while(1){
                 znaki--;
                 cyfra=pom%10;
                 *znaki=cyfra+48;
                 pom=pom/10;
                 if (pom==0) break;
        }
    
    
    write_text(znaki);
    }
    

    cos takiego dziala mi przez pewien czas,po czy pojawiaja sie krzaki...
    nie moge dopatrzec sie bledu....
  • REKLAMA
  • #2 4438465
    piti___
    Poziom 23  
    Posty: 623
    Pomógł: 67
    Ocena: 9
    Witam

    Te linie są błedne:
    znaki=znaki+ile+1;
    *znaki=0;

    w pierwszej ustalasz wskaznik na adres rowny "znaki+ile+1" czyli nie wiadomo co. W następnej lini zerujesz w pamieci komórke o tym adresie...
    
    void write_int(int liczba){
    
    char znaki[10],i; 
    
    i=0;
    
        while(1){ 
                 
                 znaki[i++]==(liczba%10) +48; 
                 liczba=liczba/10; 
                 if (liczba==0)
                 {
                  znaki[i] = 0;
                  break; 
                 }
        } 
    write_text(znaki); 
    }
    


    Jesli chciales to zrobic na wskaznikach to musialbys zaalokowac pamiec (malloc nie wszystkie kompilatory uC 8bitowych posiadaj) o jakiejs dlugosci i ustawic na ten obszar wskaznik. Lub wskaznik ustawiac na jakas znana Ci, zadeklarowana wczesniej tablice.

    Ps nie wiem czy kod jest poprawnie napisany jezeli chodzi o konwersje... dlaczego nie skorzystac z itoa (stdlib) ?
  • REKLAMA
  • #3 4438480
    dturczak
    Poziom 19  
    Posty: 416
    Pomógł: 9
    Ocena: 5
    0 na koncu daje ,bo tym sie charakteryzuje koncowka kazdego stringu.
    nie korzystam z wbudowanej funkcji bo jest pamieciozerna ;)
    znaki=znaki+ile+1; czy obszar w pamieci+dlugosc cyfry + miejsce na NULL
    no to w takim razie :
    
    //wyświetlanie liczby na lcd
    void write_int(int liczba,int uzupelnienie){
    int ile;
    int pom=liczba;
    char cyfra;
    for(ile=1;(liczba=liczba/10);ile++);
    char wyraz;
    char *znaki=&wyraz;
    znaki=znaki+ile+1;
    *znaki=0;
        while(1){
                 znaki--;
                 cyfra=pom%10;
                 *znaki=cyfra+48;
                 pom=pom/10;
                 if (pom==0) break;
        }
    
    int zera,l;
    zera=uzupelnienie-ile;
    if(zera>0){
    	for(l=1;l<=zera;l++) write_char(48);
    	  }
    write_text(znaki);
    }
    

    zalatwia sprawe?

    chyba tak,bo dziala ;)
    dodalem zaokraglanie pozycji zerami...
    czyli np. write_int(liczba,2); w przypadki liczby <10 da nam na lcd 01,02...itd...
    pozdrawiam
  • REKLAMA
  • #4 4438865
    piti___
    Poziom 23  
    Posty: 623
    Pomógł: 67
    Ocena: 9
    Musisz zarezerwowac miejsce na kilka znakow nie na jeden.

    char wyraz;
    char *znaki=&wyraz;
    znaki=znaki+ile+1;

    Kompilator wg kodu rezerwuje miejsce na jeden znak (char wyraz;). Ustawiles wskaznik na to miejsce i go przesunales. Obok tego miejsca mozesz miec inne zadeklarowane przez Ciebie zmienne ktore nadpiszesz. Musisz zadeklarowac tablice znakow. Przyjmij sobie ze bedziesz wyswietlal liczby z przedzialu od -2^16 do 2^16 (lub innego) i zadeklaruj tablice znakow
    char wyraz[6];
  • REKLAMA
  • #6 4450603
    dturczak
    Poziom 19  
    Posty: 416
    Pomógł: 9
    Ocena: 5
    no to moze zamiast
    char wyraz;
    char *znaki=&wyraz;
    to:

    char *znaki=new char[uzupelnienie];
  • #7 4452235
    pgp
    Poziom 19  
    Posty: 412
    Pomógł: 6
    Ocena: 17
    a czemu nie wykorzystasz printf w libc stdio.h ?? az taki pamięcio żerny?
  • #8 4452393
    markosik20
    Poziom 33  
    Posty: 2261
    Pomógł: 208
    Ocena: 147
    pgp napisał:
    a czemu nie wykorzystasz printf w libc stdio.h ?? az taki pamięcio żerny?


    Oj, jest "pamięciożerny" :).

    Zresztą sam autor napisał

    Cytat:
    nie korzystam z wbudowanej funkcji bo jest pamieciozerna

Podsumowanie tematu

✨ Dyskusja dotyczy implementacji funkcji wyświetlającej liczby całkowite na wyświetlaczu LCD w środowisku GCC, bez użycia pamięciożernych funkcji standardowych jak itoa() czy printf(). Problemem było niepoprawne zarządzanie pamięcią i wskaźnikami w funkcji konwertującej liczbę na łańcuch znaków, co skutkowało pojawianiem się nieczytelnych znaków ("krzaków"). Zalecano deklarację tablicy znaków o odpowiedniej długości zamiast pojedynczej zmiennej typu char, aby zarezerwować miejsce na wszystkie cyfry oraz znak końca stringu ''. Przykładowa poprawiona funkcja wykorzystuje tablicę char wyraz[10] i iteracyjnie wypełnia ją cyframi liczby od końca, a następnie wywołuje write_text() z poprawnym wskaźnikiem do początku łańcucha. Poruszono także temat uzupełniania wyświetlanej liczby zerami wiodącymi do określonej długości. Wskazano, że dynamiczna alokacja pamięci (malloc, new) może być problematyczna w mikrokontrolerach 8-bitowych. Dyskusja zawierała również sugestie użycia standardowej funkcji itoa() lub printf(), jednak autor preferował własne rozwiązanie ze względu na ograniczenia pamięciowe.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA