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

Jak rozróżnić wersję tablicową i wskaźnikową w programie C?

trepan 17 Maj 2010 22:44 2256 13
REKLAMA
  • #1 8088425
    trepan
    Poziom 9  
    Posty: 29
    Witam. Mam napisane gotowe dwa programy, ale muszę je zrozumieć..
    1. Napisz program, który jako parametr pobiera napis, a następnie zamienia małe litery na duże i odwrotnie (np. Ala - aLA). Napisz program w dwóch wersjach:
    korzystając z notacji tablicowej (odwołanie do i-tego elementu: tablica[i]) oraz korzystając z arytmetyki wskaźników (odwołanie do i-tego elementu: *(tablica+i) )

    Mój kod wygląda tak:
    #include<stdio.h>
    #include<stdlib.h>
    int i;
    char napis[10];
    
    int main(){
        printf("Podaj napis jaki chcesz wprowadzic\n");
        scanf("%s",&napis);
        for(i=0;i<10;i++)
        if(napis[i]>='a') printf("%c",napis[i]-32);
        else printf("%c",napis[i]+32);
        
        
        system("pause");
        return 0;
    }


    Pytanie- która to jest wersja??
    I o co chodzi z tym "if(napis[i]>='a') printf("%c",napis[i]-32);
    else printf("%c",napis[i]+32); " :?:

    drugi program:
    Napisz program, który sprawdza czy dana liczba jest podzielna przez 3 korzystając z cechy podzielności liczb przez 3. (jezeli suma cyfr jest podzeielna przez 3...)
    kod:
    #include<stdio.h>
    #include<stdlib.h>
    int suma,i;
    char liczba[10];
    int main(){
        suma=0;
        printf("Podaj liczbe, ktora chcesz sprawdzic czy jest podzielna przez 3\n");
        scanf("%s",liczba);
        for(i=0;i<10;i++){
        suma=suma+liczba[i];
    }
        if(suma%3==0) printf("Liczba jest podzielna przez 3\n");
        else printf("Liczba nie jest podzielna przez 3\n");
        
        system("pause");
        return 0;
    }
    


    może mi ktoś wytłumaczyć po kolei to zadanko?? tzn chodzi mi głównie o tą pętlę for. dlaczego po wczytaniu liczby, program ma zwiększać liczbę do 10?? o co tam chodzi?

    Proszę o małe wytłumaczenie tych programów najlepiej krok po kroku początkującemu laikowi;) .. W tym pierwszym to jakieś operacje na bitach, coś takiego.. zupełnie nie wiem o co chodzi..
    Z góry wielkie dzięki


    p.s w temacie "macierze" bo mam jeszcze pro.ram z macierzą, ale najpierw prosiłbym o pomoc z tymi łatwiejszymi.
  • REKLAMA
  • #2 8088657
    McMonster
    Poziom 32  
    Posty: 1942
    Pomógł: 182
    Ocena: 57
    W pierwszym wypadku to notacja tablicowa, masz zresztą podane w treści zadania, jak ona wygląda. Wskazany kawałek kodu wykorzystuje kilka szczególnych właściwości. Łańcuch jest tablicą znaków, każdy znak jest tak naprawdę liczbą (tutaj masz tablicę znaków wraz z ich kodami, tzw. tablicę ASCII), a kod dużej litery jest zawsze o 32 mniejszy od kodu małej, więc ten fragment oznacza jeśli dany znak ma kod większy lub równy, niż znak "a", to litera jest mała, więc wypisz na ekranie znak o kodzie mniejszym o 32, w przeciwnym wypadku jest to duża litera, więc wypisz znak o kodzie powiększonym o 32.

    W drugim programie nie następuje żadne zwiększanie wczytanej liczby, liczbę wczytujemy jako tekst (czyli jako tablicę znaków), gdzie jedna cyfra to jeden znak, a zmienna i jest tylko licznikiem w pętli, który służy do odczytania każdej cyfry z osobna i dodania jej do sumy.

    Szkopuł w pierwszym programie polega na tym, że gdy wprowadzi się inne znaki poza literami, to także zostaną zamienione, a chyba nie powinny, chociaż program raczej nie powinien zgłosić błędu w żadnym wypadku, a drugi program będzie działał poprawnie w bardzo nielicznych przypadkach, ponieważ gdy wprowadzona liczba ma mniej, niż 9 cyfr, to oprócz ich zsumowania dodane zostaną losowe wartości z ostatnich pól tablicy, gdyż nie zostały one na początku wyzerowane i mogą zawierać cokolwiek.
  • #3 8088919
    akaz_
    Poziom 13  
    Posty: 50
    Pomógł: 7
    Program 1, wersja pierwsza:
    
    #include <stdio.h>
    
    int main() {
        char napis[10];
        printf("Podaj napis: ");
        scanf("%s",&napis);
    
        int i;
        for(i=0; i<sizeof(napis); i++) {
            if(napis[i]>=65 && napis[i]<=95)
                napis[i]+=32;
            else if(napis[i]>=97 && napis[i]<=122)
                napis[i]-=32;
        }
    
        printf("\nPrzetworzony napis: %s", napis);
    
        return 0;
    }
    

    Program sprawdza czy podane litery są w zasięgu a-z oraz A-Z, jeśli tak to zamiana poprzez odpowiednio dodanie lub odjęcie 32, jeśli nie mieści się w zasięgu, zostawia tak jak jest.


    Program 1, wersja druga:
    
    #include <stdio.h>
    
    int main() {
        char napis[10];
        printf("Podaj napis: ");
        scanf("%s",&napis);
    
        int i;
        char *wsk = napis;
        for(i=0; i<sizeof(napis); i++) {
            if(*wsk>=65 && *wsk<=95)
                *wsk+=32;
            else if(*wsk>=97 && *wsk<=122)
                *wsk-=32;
    
            wsk++;
        }
    
        printf("\nPrzetworzony napis: %s", napis);
    
        return 0;
    }
    

    To samo jak powyżej, tyle, że na wskaźnikach.


    Program 2:
    
    #include <stdio.h>
    
    int main() {
        int liczba;
        printf("Podaj liczbe: ");
        scanf("%i", &liczba);
    
        if(liczba%3)
            printf("Liczba jest niepodzielna przez 3\n");
        else
            printf("Liczba jest podzielna przez 3\n");
    
        return 0;
    }
    

    Program sprawdza, czy liczba zwraca resztę z dzielenia.
    Jak tak, liczba nie jest podzielna. Jeśli nie zwraca reszty, to jest podzielna.


    Swoją drogą, napisałeś "Mój kod wygląda tak: ", a zaraz potem "I o co chodzi z tym if(napis) (...)", to napisałeś swój kod i pytasz się o co w nim chodzi? ;)
  • #4 8089147
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    Może jeszcze tylko słówko wyjaśnienia co do zapisu:

    akaz_ napisał:

    if(liczba%3)


    Podzielmy ten zapis na etapy: pierwszym jest wykonanie działania:



    Wynikiem tego działania jest reszta z dzielenia "liczba" przez 3.
    Dalej, w zapisie masz:



    notacja ta sprawdza, czy warunek w nawiasie jest prawdziwy, czy fałszywy. Jak to się ma do naszego działania? Otóż "fałsz" reprezentowany jest jako liczba 0, natomiast liczby > 0 to "prawda". Inaczej mówiąc, powyższy zapis sprawdza, czy:

    
    if ( (liczba % 3) > 0 )
    ..........
    


    Czyli, gdy "liczba" będzie liczbą niepodzielną przez 3, wynik tego działania będzie różny od zera, co spowoduje zadziałanie powyższego warunku "if".

    powodzenia ;)
  • REKLAMA
  • #5 8089416
    trepan
    Poziom 9  
    Posty: 29
    akaz_ napisał:

    Swoją drogą, napisałeś "Mój kod wygląda tak: ", a zaraz potem "I o co chodzi z tym if(napis) (...)", to napisałeś swój kod i pytasz się o co w nim chodzi? ;)


    "mój kod" oznacza kod, który posiadam :D .. sam go nie napisałem


    Dzięki wam za pomoc.. później postaram się to przeanalizować.Jak nie będę czegoś wiedział to napiszę ;)
  • #6 8099271
    trepan
    Poziom 9  
    Posty: 29
    Mam takie pytanka:
    -Jak te dwa zadanka mają się do wskaźników i tablic ??
    Bo właśnie omawiam takie tematy, a nie widzę, żeby w nich coś było o tym ;)

    - może mi ktoś lekko wytłumaczyć dlaczego
    int suma,i;
    char liczba[10];
    umieszczamy przed int main() ??
    przeważnie int main bylo pierwszą funkcją.. A jak dam to na początku to program nie działa poprawnie. Dlaczego tak się dzieje?? ;)
  • #7 8099757
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    trepan napisał:

    -Jak te dwa zadanka mają się do wskaźników i tablic ??


    W tym zadaniu tablicą jest łańcuch tekstowy. Odwołujesz się do jej elementów poprzez operator [].
    Wskaźnikiem jest... również to samo :D "napis" jest wskaźnikiem na pierwszy element tablicy "napis".

    trepan napisał:

    - może mi ktoś lekko wytłumaczyć dlaczego
    int suma,i;
    char liczba[10];
    umieszczamy przed int main() ??


    Bo to są zmienne globalne, w odróżnieniu od zmiennych lokalnych. Zmienne globalne są widziane wszędzie, natomiast lokalne tylko lokalnie ;) czyli np. w obrębie aktualnej funkcji. Poczytaj o haśle "zasięg widoczności zmiennych".
  • #8 8099816
    trepan
    Poziom 9  
    Posty: 29
    ok już wiem wszystko ;)
    Ale jak zmienną globalną dam jako zmienną lokalną to też program działa. W którym momencie może przestać działać, albo może wyniknąć z tego błąd?
  • REKLAMA
  • #9 8099845
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    Gdy będziesz miał więcej funkcji, niż tylko jedną main. Wtedy zmienne w niej zadeklarowane nie będą widoczne w tej drugiej.
  • #10 8100107
    trepan
    Poziom 9  
    Posty: 29
    Jeszcze mam pytanie co do drugiego programu..
    Tam chodzi o kod ANCII- to wiem. Duże litery są 32 liczby mniejsze od małych..
    A jak wprowadzić do programu ten ANCII?? Możecie mnie nie zroumieć ;)..
    Mamy tablicę i każda wpisana litera jest przyporządkowana do kolejnego elementu tablicy.. i np dla elementu 5 sprawdzamy, czy napis[i] czyli litera znajdująca się w piątym elemencie tablicy jest większa od znaku "a" (czyli liczby 97) .
    Kompilator sam przekształca sobie liczbę na kod ANCII ?? Czyta daną liczbę od razu w tym kodzie?
    Bo mogę zapisać "napis[i]<=97" tak?
    Na jakiej to zasadzie działa, że nie przyrównuje mi do jakiejś tam liczby 97 tylko do 97 w kodzie ANCII ??
    Czy na to wskazuje m.in char, która przechowuje znaki.. ?
    Ahh.. pewnie nie rozumiecie mojego pytania ..
  • #11 8100304
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    1. albo ANSI albo ASCII ;)

    2. zmienna typu char to zmienna, która może być przedstawiona zarówno jako znak, jak i jako jednobajtowa liczba. Wprowadzony znak 'a' jest równocześnie, automatycznie, liczbą 97.

    Dodano po 32 [sekundy]:

    trepan napisał:
    Bo mogę zapisać "napis[i]<=97" tak?


    Tak, dokładnie tak - pod warunkiem, że mówimy cały czas o typie char.
  • #12 8100347
    trepan
    Poziom 9  
    Posty: 29
    Ahaa.. Czyli żeby użyć kodu ANSI musimy użyć funkcji char.. ok dzięki ;)
  • #13 8100436
    beluosus
    Poziom 25  
    Posty: 362
    Pomógł: 123
    Ocena: 18
    trepan napisał:
    Ahaa.. Czyli żeby użyć kodu ANSI musimy użyć funkcji char.. ok dzięki ;)

    Może trochę podstaw... char to nie funkcja tylko typ podstawowy. Char ze znakiem (signed) przyjmuje wartości od -128 do 127, char bez znaku (unsigned) od 0 do 255. 'a', 'X' czy też '\t' to są liczby (jak wyżej napisano) ale dla wygody programisty mogą być zapisane na różne sposoby (liczbowy, literowy), dla kompilatora to nieistotne. ASCII (czyt. aski) to właśnie standard przyporządkowania odpowiednich znaków do liczb. Standard jest po to żeby wszyscy wiedzieli, że pod numerkiem 97 kryje się literka 'a'. Kod ASCII jest 7 bitowy, a komputery operują na 8 bitach więc kolejny bit został wykorzystany do rozszerzenia tablicy znaków. Zawsze jednak znaki o numerach od 0 do 127 mają ustalone wartości, a znaki od 128 do 255 zależą od standardu rozszerzającego (ISO 8859-2, CP1250, UTF8 itd).

    ASCII w wiki.
    ANSI - organizacja standaryzująca.
  • REKLAMA
  • #14 8101232
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    trepan napisał:
    żeby użyć kodu ANSI musimy użyć funkcji char


    Teraz to ja nie rozumiem :D
    Tak jak mówi poprzednik - tak jak liczba jest typu np. int, float czy double, tak znak (nie mówimy tutaj dla uproszczenia o Unicode i innych wynalazkach) jest typu char. Jest to bajt, a czy jego zawartość obejrzysz jako liczbę, czy jako odpowiadający mu wg standardu ASCII znak - "wsio ryba".

Podsumowanie tematu

✨ W dyskusji poruszono temat różnicy między notacją tablicową a arytmetyką wskaźników w języku C, w kontekście programów zamieniających małe litery na duże i odwrotnie. Użytkownik przedstawił kod, który wykorzystuje tablicę znaków do przetwarzania łańcucha tekstowego. Odpowiedzi wyjaśniają, że notacja tablicowa polega na odwoływaniu się do elementów tablicy za pomocą operatora [], podczas gdy wskaźniki umożliwiają dostęp do tych samych elementów poprzez arytmetykę wskaźników. Wskazano również na znaczenie kodu ASCII, który przypisuje wartości liczbowe do znaków, co jest kluczowe dla działania programów. Uczestnicy dyskusji podkreślili, że zmienne globalne są widoczne w całym programie, podczas gdy lokalne tylko w obrębie funkcji, co ma znaczenie przy projektowaniu kodu.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA