Programowanie w języku C/C++

Tablice

  • 2006-06-18 15:02
  • 12 komentarzy
  • 12402 odsłony
  • Oceń ten tekst jako pierwszy

Czym jest tablica?


Jeśli wiesz już czym jest zmienna, zrozumienie pojęcia tablica (ang. array) nie powinno sprawić Ci problemów. Tablica jest po prostu zbiorem określonych zmiennych w określonej ilości ułożonych (w większości implementacjach) obok siebie. Takie zmienne określa jedna wspólna nazwa po której zapisujemy indeks elementu. Tablica może być statyczna -- której rozmiar jest stały i wiadomy już podczas kompilacji (pamięć jest alokowana w obrazie aplikacji lub przy starcie programu na podstawie segmentu .data), i dynamiczna -- której pamięć (jak i rozmiar) jest alokowany podczas pracy programu.

Tablica statyczna


Tablice statyczne w C/C++ deklarujemy w następujący sposób:

int tablica[5];
tablica[1] = 1;


pamiętając, że wartość w nawiasach kwadratowych musi być wartością stałą (którą kompilator zna już podczas kompilacji).

Tablica dynamiczna


Jednowymiarowa


W językach C i C++ operacje na wskaźnikach można dokonywać podobnie jak operacje na tablicach. Dlatego przy deklarowaniu tablicy dynamicznej postępujemy następująco:

int *tablica = new int[5];
tablica[1] = 1;


należy zwrócić uwagę na to, iż zamiast stałej wartości (w tym wypadku 5) możemy podać zmienną (stąd tablica dynamiczna).
Zawsze należy pamiętać o zwolnieniu przydzielonej pamięci kiedy nie jest już nam potrzebna
delete [] tablica; 
tablica = 0; 


Dwuwymiarowa


Tak wygląda tworzenie tablicy 100x50 i korzystanie z niej;

int **tab2 = new int *[100];
for ( int i = 0; i < 100; ++i )
   tab2[i] = new int [50];
tab2[64][32] = 16;
std::cout << tab2[64][32] << std::endl;  // wypisze 16; 


Po zakończeniu usuwamy ją z pamięci

for ( int i(0); i < 100; ++i )
   delete [] tab2[i];
delete [] tab2; 


Zastosowanie


Tablice w c++ są bardzo przydatne, dlaczego? Wyobraź sobie, że chcesz napisać program do obliczania średniej. Załóżmy iż będzie on obliczał średnią z 15 ocen, kod więc wyglądał by mniej więcej tak:

#include <iostream>
 
using namespace std;
 
int main()
{
   int ocena1, ocena2, (...) ocena15;
 
   cout <<"Podaj oceny\n";
   cin >>ocena1>>ocena2 (...) >>ocena15;
   cin.ignore();
 
   int srednia;
   srednia = (ocena1 + ocena2 (...) +ocena15) / 15;
 
   cout <<"Srednia wynosi: "<<srednia;
 
   return 0;
}


Kod powyżej oprócz tego, że jest nie wygodny i nieprzyjemny, może doprowadzić do szału jeśli np trzeba by policzyć średnią 1000 elementów. Dlatego wymyślono tablice.

Schematyczna dekalaracja tablicy

typ_zmiennej nazwa_tablicy[liczba_elementów_tablicy]


czyli na przykład
int tablica[100]  //deklaracja tablicy stu elementowej liczb całkowitych
char tablica_2[20]   //20 elementowa tablica znaków


gdy deklarujemy tablice musimy pamiętać, że jej romiar musi być znany w czsie deklaracji, czyli można zrobić na przykład tak:

cout <<"Podaj liczbe: ";
int jakas_liczba;
cin >>jakas_liczba;
cin.ignore();
int jakas_tablica[jakas_liczba];


stworzona zostanie w ten sposób tablica o rozmiarze przez nas podanym ;)

podandto należy pamiętać, iż tablice są zawsze indeksowane od zera, co to znaczy? otóż jeśli mamy tablice 10 elementową to odwołuje my się do jej poszczególnych elementów w licząc od zera, czyli mamy tab[0], tab[1], (...) tab[9];

Znając już teraz tablice możemy usprawnić działanie naszego programu ;)
#include <iostream>
 
using namespace std;
 
int main()
{
    int rozmiar;
    cout <<"podaj ilosc liczb: ";
    cin >>rozmiar;
    cin.ignore();
 
    int tablica[rozmiar];
    int suma = 0;
    for (unsigned int i = 0; i < rozmiar; ++i)  //pobieranie liczb...
    {
        cout <<"Podaj liczbe nr "<<(i+1)<<" : ";
        cin >>tablica[i];
        cin.ignore();
        suma += tablica[i];     //sumowanie elementów...
    }
    cout <<"\nsrednia wynosi: "<<(suma / rozmiar)<<endl;
    getchar();
 
    return 0;
}


Zobacz też:

12 komentarzy

Brak avatara
ETO 2014-01-28 10:12

Może prosciej byłoby użyc listy powiązanej jedno lub dwukierunkowej? Strukturę elementu tablicy można potraktować jako pojedynczy rekord który może zawierać pola róznych typow, a tego w typowej tablicy nieda sie zrobić.Taka dynamiczna tablica bedzie mogła w dowolny sposób powiekszać i zmniejszać swój rozmiar...

wilhelm 2012-03-12 21:04

@wojmysz - tak ma być. Jeśli chcesz powiększyć tablicę musisz utworzyć nową większą, skopiować do niej starą. Jest to poniekąd bardzo sensowne. Tablica w pamięci zawsze zajmuje kolejne komórki pamięci. Wyobraź sobie taką sytuację:
1. Tworzysz tablicę
2. Tworzysz coś innego w obszarze pamięci zaraz za końcem tablicy
3. Rozszerzasz tablicę o adresy zaraz za nią
W takim przypadku obiekty utworzone w pkt drugim zostałyby nadpisane rozszerzoną tablicą. Nie wiem czy napisałem to zrozumiale, no ale gwarantuje że się nie da

wojmysz 2011-12-18 14:44

Od kilku godzin siedzę na róznych forach i nigdzie nie znalazłem rzeczowej informacji na temat powiększania tablic dynamicznych. Niby sprawa jest prosta, ale przy powięszaniu tablicy dynamicznej (w końcu do tego służy) tracę całą dotychczasową ich zawartość. Może ja coś źle robię, a może tak musi być, ale nigdize na ten temat nie znazłem informacji

Flapek 2009-05-01 11:49

Witam wszystkich serdecznie. Mam pytanie czy ten ostatni program działa poprawnie ? . Bo przy debugowaniu sypie mi błędy, chodzi o linijki kodu:

int tablica[rozmiar];

błędy w tej linii występujące :

 error C2057: expected constant expression

error C2466: cannot allocate an array of constant size 0

error C2133: 'tablica' : unknown size

i jedno ostrzeżenie w linii:

for (unsigned int i = 0; i < rozmiar; ++i)  //pobieranie liczb...

warning C4018: '<' : signed/unsigned mismatch

z góry dziękuje za odpowiedź

winerfresh 2008-10-31 07:20

jeśli chce się zrobić tablicę dynamiczną to trzeba skorzystać z new:

int tablica = new int[rozmiar]

cyriel 2008-07-17 00:10

@Cold: Bo rozmiar tablicy nie jest znany podczas kompilacji. Niektóre kompilatory tego (słusznie) nie przepuszczją.

Coldpeer 2007-11-02 17:46

Jak to niezgodna?

MarcelS 2007-05-05 11:09

Jestem lamerem - wiem. Ale zastanawia mnie jedna rzecz. Skoro na początku jest napisane, że rozmiar tablicy statycznej musi być znany podczas kompilacji to dlaczego w ostatnim programie jest napisane:
int tablica[rozmiar];
Przecież to jest deklaracja niezgodna ze standardami.

A gwiazdki są ważne bo to jest deklaracja wskaźnika. dwie gwiazdki to "Wskaźnik do wskaźnika" Poczytaj sobie chociażby nawet Grębosza.

AklimX 2006-11-13 18:51

@Miczu: tak, te gwiazdki są ważne i oznaczają liczbę wymiarów tablicy :)

Miczu 2006-11-12 22:10

Czy ' * ' przy nazwie tablicy jednowymiarowej i ' ** ' przy dwuwymiarowej jest ważne, czy to tylko tak wymyślona nazwa... a jestli to ważne to jaką to ma funkcję? Czy chodzi o to, że ilość ' * ' oznacza ilu wymiarowa jest tablica???

Odpowiedz na moje pytania mile widziana :P

Wolverine 2006-06-16 23:01

Poprzedni art walnalem do ostatniego headera, reszte dopisalem imo w troche bardziej eleganckim stylu