Elektroda.pl
Elektroda.pl
X
Deimic One - Szkolenia
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Kurs programowania C/C++. Część 1.2 - Tablice i wskaźniki

jankol-el 18 Paź 2013 11:10 4188 0
  • Kurs programowania C/C++. Część 1.2 - Tablice i wskaźniki


    Kurs:
    Część 1.0 - Start w języku C
    Część 1.1 - Typy danych i zmienne
    Część 1.2 - Tablice i wskaźniki
    Część 1.3 - Operatory
    Część 1.4 - Instrukcje i pętle

    Tablice

    Wiemy już jak przechowywać w pamięci liczby całkowite, znaki, liczby zmiennoprzecinkowe itd. Mówię tu o pojedynczych danych, bo gdy użyjemy np.
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Mamy w pamięci zapisaną gdzieś i, która jest pojedynczą zmienną typu całkowitego, mamy c które jest jednym, samotnym znakiem umieszczonym wśród komórek pamięci RAM, i mamy biedną, samotną liczbę zmiennoprzecinkową f. Strasznie smutne, samotne zmienne! Jeśli potrzebujemy, by zmienne nie czuły się takie samotne, bo tego wymaga nasz program, albo po prostu chcemy w tym celu tworzymy tablicę. Najprościej mówiąc, tablica jest to ciąg elementów tego samego typu, które zajmują ciągły obszar w pamięci. Tymczasem nasze pojedyncze zmienne mogą być rozrzucone po niej. Tablica wygląda modelowo mniej więcej tak:
    Kurs programowania C/C++. Część 1.2 - Tablice i wskaźniki

    Jak widać elementy w tablicy numerujemy od zera, ZAWSZE!
    Stwórzmy sobie tablicę liczb całkowitych:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Mamy tablicę, nazywającą się niesamowicie nietuzinkowo: tablica.
    Nasza tablica ma 10 elementów. Gdyby każdy element wziąć osobno to musimy pamiętać, że elementy są liczone od 0 do 9 w tym przypadku. Odwołać się możemy do każdego elementu podając w nawiasie kwadratowym ( [ i ] ) liczbę elementu. Odwołanie się do pierwszego elementu:




    Kod: c
    Zaloguj się, aby zobaczyć kod

    Do ostatniego:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Oczywiście w takiej niezapełnionej niczym konkretnym tablicy będą przypadkowe wartości, jeśli mowa o naszej konkretnej tablicy, która jest typu int, możemy w niej znaleźć np. -4, 5, 0, 1235, 454 itd.
    Gdybyśmy wpisali pomiędzy [ i ] więcej niż dziewięć, weszlibyśmy na obszar pamięci który nie należy do naszej tablicy. "Pół biedy" jeśli odczytujemy wartości. Zapis może spowodować różne szkody. To bardzo ważne, bo jak wspomniałem, jest to ciągły obszar elementów wybranego typu.
    A pamięć nie jest przecież zainstalowana w komputerze tylko dla naszego programu. Mamy przecież uruchomione procesy w tle, które również używają tej samej pamięci, mamy przecież system operacyjny.

    Ogólnie więc tablice tworzymy tak:
    TYP NAZWA_TABLICY[ROZMIAR];
    A odwołujemy się do niej tak:
    TYP NAZWA_TABLICY[ROZMIAR-1];
    (bo od zera zawsze liczymy!)

    Możemy do takiej tablicy wpisać jakieś wartości i je w niej przechowywać, oraz zmieniać. Prosty przykład w DevC++:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Po uruchomieniu wpisałem wartość 123.
    Efekt:

    Kurs programowania C/C++. Część 1.2 - Tablice i wskaźniki

    W dalszej części kursu powrócimy do tablic z pewnymi ciekawymi sztuczkami! ;)


    Wskaźniki
    Nadszedł czas, by zmierzyć się z trudniejszym zagadnieniem jakim są wskaźniki (ang. pointer).
    Spokojnie, da się zrozumieć i opanować. Mimo, że na początku nie zobaczymy zalet, ani sensu używania takich "cudów", warto poświęcić na nie czas. Czym jest wskaźnik?
    Dla każdego typu danych istnieje skojarzony z nim typ wskaźnikowy.
    Szkielet tego wygląda tak:
    KONKRETNY_TYP_ZMIENNEJ* JAKAŚ_NAZWA;
    Ta gwiazdka to nie jest przypadkowo wciśnięty przeze mnie znak na klawiaturze.
    Tak tworzymy wskaźnik.
    Czytamy od lewej do prawej strony. W tym przypadku JAKAŚ_NAZWA wskazuje(* - można pamiętać jako "wskazuje") na KONKRETNY_TYP_ZMIENNEJ.

    Przykłady z użyciem znanych nam typów:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Co, z czym się je? Mamy zmienne i możemy je wskazać, a właściwie nie tyle je, co ich miejsce w pamięci. To dla nas programistów taki wskaźnik jak u nauczyciela geografii ten "patyczek".

    Definicja czysto książkowa:
    Zbiorem wartości typu X* są wskaźniki do obiektów typu X. Do zbioru wartości typu X należy również wskaźnik pusty, oznaczany jako 0 lub NULL. Jednym z możliwych wystąpień typu wskaźnikowego jest zmienna wskaźnikowa, której definicja ma postać następującą:
    nazwa_typu_wskazywanego *nazwa_zmiennej_wskaźnikowej;
    Wartościami zmiennej wskaźnikowej mogą być wskaźniki do uprzednio zdefiniowanych obiektów (zmiennych, stałych). Jeżeli nie chcemy, aby zmienna wskaźnikowa wskazywała na jakiś obiekt, przypisuje się jej wartość zero lub NULL.


    Przykład ode mnie, tym razem w Code::Blocks, może nieco trudny na początek, ale tłumaczę wszystko za moment.
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Efekt:
    Kurs programowania C/C++. Część 1.2 - Tablice i wskaźniki

    Co my tu mamy? Komentarze z numerami posłużą mi, by pokazać co w którym punkcie jest.

    1. Deklaruję, że coś, co nazywa się "wsk1" to wskaźnik na jakąś zmienną typu int.
    2. Tutaj to samo, z tym, że wskaźnik ma nazwę "wsk2". Zastanawiające jest pewnie to moje zamieszanie z gwiazdką. Otóż, pokazuję tym, że nie ma różnicy, czy gwiazdkę postawimy przy typie, czy przy nazwie naszej zmiennej wskaźnikowej. Ważne, by używając potem wskaźnika postawić przy nim gwiazdkę, przy deklaracji nie ważne jest gdzie postawimy.
    3. Tu z kolei definiujemy, czyli deklarujemy i inicjalizujemy od razu zmienną. Nazwałem zmienną "l_calkowita1", bo typ int jest typem liczb całkowitych w gwoli przypomnienia. Nadałem jej wartość 456.
    4. Sytuacja jak powyżej, tylko zmienną nazwałem "l_calkowita2" i nadałem jej wartość 654.
    W punktach 5. i 6. rozkazałem jak gdyby wskaźnikom pokazać na konkretne miejsce, czyli na miejsce, gdzie są w pamięci umieszczone nasze zmienne typu int. Od tej pory "wsk1" pokazuje na adres w pamięci w którym "siedzi" zmienna "l_calkowita1". Analogicznie jest z drugim wskaźnikiem. Wspomniany w poprzedniej części znaczek ampersand - & - ma proste zadanie, musi wyciągnąć adres zmiennej. Ten adres jest zapamiętany przez wskaźnik. Może nie jest to proste, ale jeśli ktoś tego nie rozumie proszę pisać do mnie PW.
    Zauważmy jednak bardzo ważną rzecz! nasze "wsk1" i "wsk2" nie mają przed sobą gwiazdek.
    7. Dla klarowności wypisujemy sobie jakie wartości mają nasze zmienne.
    8. Znów posługując się & wyciągamy (wyłuskujemy) adres zmiennych, by go porównać w dalszej części ze wskaźnikami. Zauważyć należy, że typu znakowego %x, by móc wyświetlić kod heksadecymalny adresu w pamięci, aby było profesjonalnie. W informatyce używamy często innych systemów liczbowych, o czym także będzie można poczytać w tym kursie. Oczywiście użycie %d nie będzie błędem, wyświetli się wówczas wartość dziesiętna tego adresu.
    9. Tu napisałem trochę tak na skróty, bo nie mają takich wartości te wskaźniki, ponieważ ich wartość to adres komórki pamięci, a nie wartość tej zmiennej na którą wskazują. To tak tylko umownie. Tu pojawia się już *, która wyłuskuje wartość tego na co pokazują te wskaźniki. Łatwo potem zauważyć, że nie różni się to w ogóle od wartości wcześniej przedstawionych zmiennych.
    10. Tutaj bez gwiazdki, czyli wreszcie mamy do czynienia z tą prawdziwą wartością zmiennej wskaźnikowej - adresem! Również posłużyłem się tutaj %x w takim samym celu jak w punkcie 8.

    Ważną rzeczą w temacie wskaźników i co trzeba pamiętać bezwzględnie, że wskaźnik danego typu może pokazać tylko na zmienną takiego samego typu, bo błędem okrutnym jest:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Wiąże się to z przygotowaniem przez kompilator miejsca w pamięci dla danego typu. W poprzednich częściach pokazałem taką tabelkę:

    Kurs programowania C/C++. Część 1.2 - Tablice i wskaźniki

    To trochę tak, jakbyśmy ścielili łóżko dla kogoś niskiego, a kazali położyć się tam dwumetrowemu koszykarzowi. Rozmiar jednak to nie wszystko, jeszcze inne zagadnienia wchodzą tu w grę. Dlatego tak ważne jest, by wskaźnik pewnego typu pokazywał na adres zmiennej takiego samego typu.


    Póki co, w tej części porzucimy zagadnienia tablic i wskaźników. Wrócimy do nich niebawem. Radzę czasem zaglądać w przeczytane już materiały, bo kurs rozwija się na bieżąco. Dodaję niekiedy jakieś szczegóły, poprawiam drobne błędy.



    Literatura:
    -Język ANSI C. Programowanie. Wydanie II
    Autorzy: Brian W. Kernighan, Dennis M. Ritchie
    -Symfonia C++ Standard. Tom 1-2. Wydanie III
    Autor: Jerzy Grębosz
    -Czysty kod. Podręcznik dobrego programisty
    Autor: Robert C. Martin


    Fajne!
  • Deimic One - Szkolenia