Jeżeli w języku C++ stykamy się z grupą zmiennych tego samego typu, to należy zdawać sobie sprawę, że mogą one być zorganizowane w tablicę. Tablica, z angielskiego array, jest pewną strukturą, która złożona jest z elementów tego samego typu zajmujących następujący po sobie obszar w pamięci. Każda tablica w języku C++ składa się z elementów, a elementy tej tablicy mogą być typy int, long, short, float, char, wskaźnikowego, same w sobie mogą być tablicami, a nawet strukturami i klasami. Każda definicja tablicy składa się z jej identyfikatora, typu oraz wymiaru. Wymiarem tablicy, określającym ilość elementów, które dana tablica zawiera, stanowi ujęta w nawiasy prostokątne cyfra. Cyfra ta musi być większa lub równa jedności, aby deklaracja tablicy miała jakikolwiek sens. Liczba elementów musi być wyrażeniem stałym całkowitego typu, które można obliczyć jeszcze w fazie kompilacji, innymi słowy nie jest możliwe używanie zmiennej jako cyfry określającej rozmiar tablicy. Tablica jest uporządkowanym zbiorem elementów tego samego typu. Typ tychże elementów stanowi zarazem typ tablicy. Przykładowo, jeżeli chcemy przechowywać w tablicy liczby typu int, to tablica również będzie typu int. Określony porządek oznacza, że elementy nie są w niej przechowywane w sposób losowy, lecz wszystkie one są uporządkowane w przydzielonych im miejscach pamięci.
Tablica to typ pochodny. Oznacza to, że w momencie gdy weźmiemy jakiś typ danych, na przykład int i z tego typu elementów możemy zbudować tablicę, wtedy jest to tablica typu int. Jeżeli potrzebujemy 20 zmiennych typu int to deklarujemy tablicę tych elementów w następujący sposób:
int aiTablica[20];
Dzięki powyższej definicji rezerwujemy w pamięci miejsce dla dokładnie 20 liczb typu int. Rozmiar zdefiniowanej w ten sposób tablicy musi być liczbą stałą, która znana jest z góry w trakcie kompilacji. Warunek ten jest konieczny do stworzenia tablicy, ponieważ kompilator musi wiedzieć ile miejsca w pamięci powinien zarezerwować na daną tablicę. Do poszczególnych elementów tablicy możemy się dostać dzięki nazwie tablicy lub obliczając ich położenie w tablicy. Opisana powyżej postać dostępu jest nazywana indeksowaniem. Przykładowo zapis:
int aiTablica[iLicznikTablicy];
Odpowiada za deklarację tablicy typu int, gdzie aiTablica[iLicznikTablicy] nazywane są zmiennymi indeksowanymi. Każda zmienna indeksowana numerowana jest od zera, dlatego też pierwszym elementem naszej tablicy jest aiTablica[0], drugim aiTablica[1] i tak dalej. Podsumowując aiTablica[iLicznikTablicy] ma iLicznikTablicy elementów, które numerowane są w poniższy sposób:
aiTablica[0], aiTablica[1], … aiTablica[iLicznikTablicy-1]
Niezależnie od tego czy dany obiekt jest standardowym typem C++, czy też jest typem zdefiniowanym przez użytkownika możemy umieścić go w tablicy. W momencie deklaracji tablicy podajemy typ jej elementów oraz jej rozmiar. Kompilator oblicza ile miejsca powinien zarezerwować dla deklarowanej właśnie tablicy. Tablica z pierwszego przykładu jest tablica pięcioelementową i zawiera elementy o numerach 0, 1, 2, 3 oraz 4. Elementy te mogą być wczytywane z klawiatury przy pomocy funkcji scanf(), albo można przypisać im wartości już bezpośrednio w kodzie programu. Ponieważ każdy element jest typu int, tablica ta też może być typu int, niemożliwym jest zdarzenie, że jeden element jest typu float a pozostałe typu int, kompilator natychmiast zgłosi błąd w takim wypadku.
Jeżeli po raz pierwszy deklarujemy tablicę typów wbudowanych takich jak char, czy też int, możemy ją od razu zainicjalizować. Aby poprawnie zainicjalizować tablicę należy po nawiasie kwadratowym umieścić znak równości, a następnie wprowadzić w nawiasy klamrowe listę wartości inicjalizujących poszczególne komórki tablicy, rozdzielając je przy tym przecinkami. Przykład inicjalizacji znajduje się poniżej:
int aiTablica[5] = { 1, 2, 3, 4, 5 };
Udało nam się zadeklarować tablicę aiTablica, jako tablicę złożoną z pięciu wartości całkowitych. Kolejnym elementom tablicy przypisywane są poniższe wartości:
aiTablica[0] = 1;
aiTablica[1] = 2;
aiTablica[2] = 3;
aiTablica[3] = 4;
aiTablica[4] = 5;
Jeżeli pominiemy rozmiar naszej tablicy, stworzona zostanie tablica o rozmiarze na tyle dużym, by możliwe było pomieszczenie wszystkich elementów inicjalizujących. Pisząc poniższą deklarację, stworzymy identyczną tablicę jak w poprzednim przykładzie:
int aiTablica[] = { 1, 2, 3, 4, 5 };
Jeżeli chcemy poznać rozmiar danej tablicy możemy go obliczyć pisząc taką przykładową instrukcję w kodzie programu:
const unsigned int uiDlugoscTablicy = ( sizeof(aiTablica) / sizeof(aiTablica[0]) );
W powyższej linijce do stałej uiDlugoscTablicy wpisywana jest wartość typu unsignet int, która jest wynikiem dzielenia rozmiaru w pamięci całej tablicy i rozmiaru w pamięci pojedynczego elementu tablicy. Otrzymany wynik daje nam liczbę elementów, jaką dana tablica zawiera. Nie wolno inicjalizować więcej elementów tablicy niż wynosi jej rozmiar. Poniższy zapis spowoduje błąd kompilacji z powodu zainicjalizowania sześciu elementów w pięcioelementowej tablicy:
int aiTablica[5] = { 1, 2, 3, 4, 5, 6 };
Dostęp do poszczególnych danych w tablicy odbywa się w następujący sposób: musimy określić numer interesującego nas elementu tablicy przy pomocy operatora indeksowego [ ], a następnie przypisać otrzymaną wartość spod odpowiedniej komórki tablicy do określonej zmiennej. Tablica, jak już zostało napisane wcześniej, może zostać zainicjalizowana od razu w trakcie deklaracji:
int aiTablica[5] = { 1, 2, 3, 4, 5};
Tablice mogą mieć dowolne nazwy, które zgodne są z zasadami nazywania wszystkich rodzajów zmiennych, nie mogą mieć jednak identycznej nazwy jak inna tablica lub zmienna znajdująca się w obrębie tego samego bloku danych. Nie można zatem deklarować w tym samym bloku zmiennej int tablica; oraz tablicy int tablica[];.
Opisywane dotychczas tablice odnosiły się wyłącznie do jednego wymiaru. Język C++ umożliwia jednak stosowanie także tablic dwuwymiarowych, które możemy zdefiniować w razie potrzeby. Aby to zrobić należy dopisać przy definicji drugą parę nawiasów kwadratowych, a następnie wpisać w nią cyfrę kolejnego wymiaru tablicy. Każdy wymiar tablicy musi być liczbą stałą lub zmienną typu const. Możliwe jest tworzenie tablic zarówno dwuwymiarowych jak i wielowymiarowych. Takie tablice można wyobrazić sobie jako tablice tablic. Przykładowa deklaracja tablicy dwuwymiarowej wygląda następująco:
int aiTablicaDwuwymiarowa[5][5];
Definicja ta czytana jest w następujący sposób: zadeklarowana została tablica dwuwymiarowa, i każdy z wymiarów tej tablicy wynosi 5. Oznacza to, że powyższa tablica składa się z 25 (5 wierszy i 5 kolumn) elementów typu int. Do poszczególnych elementów tej tablicy odwołujemy się w następujący sposób:
aiTablicaDwuwymiarowa[numer_wiersza][numer_kolumny];
Podobnie jak zmienne oraz funkcje, tak i tablice wymagają deklaracji przed ich użyciem. Inaczej mówiąc musimy poinformować komputer ile miejsca powinien zarezerwować w pamięci oraz w jaki sposób ma rozmieścić poszczególne elementy tablicy. Elementami tymi mogą być liczby, pojedyncze znaki, łańcuchy znaków i tym podobne. Obiektami tego typu operują wszystkie języki programowania. Programowanie obiektowe oznacza jednak, że możemy używać jako zmiennych, czy elementów tablicy właśnie różne stworzone przez nas obiekty. Jeżeli spojrzymy z punktu widzenia komputera, obiekt jest czymś, co zajmuje określony obszar w pamięci i z czym wiemy jak postępować.
int aiTablica[5];
Powyższa deklaracja mówi komputerowi, że powinien zarezerwować w pamięci 5 kolejnych komórek pamięci zawierających każda liczbę całkowitą typu int (która zajmuje w pamięci 2 bajty). Powstała tablica jednowymiarowa będzie odtąd nosić nazwę aiTablica[, natomiast jej kolejne elementy zostaną ponumerowane przy pomocy odpowiednich indeksów. Specjalny rodzaj tablic stanowią tablice przeznaczone do przechowywania łańcuchów znakowych, głównie liter. Przykładowa deklaracja takiej tablicy wygląda w poniższy sposób:
char cTablicaZnakow[20];
Powyższa definicja określa, że cTablicaZnakow stanowi tablicę 20 elementów, które są znakami. Możemy umieścić w tej tablicy tekst, dzięki faktowi, że każdy z jej elementów składowych przeznaczony jest do przechowywania liczbowej reprezentacji któregokolwiek z kodów ASCII, w tym również liter.
Podsumowując tablice są wykorzystywane do przechowywania określonej ilości elementów tego samego typu. Deklaracja tablicy przypomina deklarację zmiennej, jednak podajemy po jej nazwie, w nawiasach kwadratowych, ilość elementów, z których tablica ta będzie się składać. Przypominamy rodzaje deklaracji tablic:
int aiTablica[5]; // jednowymiarowa tablica 5 liczb całkowitych
int aiTablicaDwuwymiarowa[5][5]; // dwuwymiarowa tablica 25 liczb całkowitych
int aiTablica[] = { 1, 2, 3, 4, 5 }; // deklaracja wraz z inicjalizacją kolejnych wartości elementów tablicy
char cTablicaZnakow[] = "przykładowy tekst" // przy inicjalizacji tablicy znaków zwykle nie podajemy jej rozmiaru, ponieważ jest on liczony przez kompilator na podstawie długości wprowadzonego tekstu, znak końca łańcucha jest dodawany automatycznie
char cTablicaZnakow[] = {'p', 'r', 'z', 'y', 'k', 'ł', 'a', 'd', 'o', 'w', 'y', ' ', 't', 'e', 'k', 's', 't', ' '}; // przy inicjalizacji tablicy znaków element po elemencie, nie należy zapominać o znaku końca łańcucha nazywanym NULL i oznaczanym ' '
Odwołanie do konkretnego elementu tablicy następuje w poniższy sposób, w którym wykorzystano przypisanie nowej wartości do danej komórki tablicy:
aiTablica[5] = 23;
aiTablicaDwuwymiarowa[5][2] = 64
Dzięki wykorzystaniu tablic upraszczamy znacznie programowanie oraz sprawiamy, że nasz kod staje się dużo bardziej elegancki. Jeżeli mamy wprowadzać 10 zmiennych o podobnej nazwie i spełniających w programie podobne funkcje, to lepiej zdefiniować tablicę o rozmiarze 10, na której w prosty sposób przeprowadzimy te same operacje, co dla pojedynczych zmiennych. Jest to zatem rozwiązanie bardzo praktyczne. Tablice są pożyteczne i wręcz nieodzowne dla programistów pracujących w języku C++, są chętnie wykorzystywane, również ze względu na dużą efektywność w pisaniu programów z ich wykorzystaniem.
Poniżej zamieszczony został przykładowy program, który na początku ustala rozmiar tablicy, a później po wprowadzeniu wszystkich danych oblicza liczbę dodatnich elementów oraz ustala ich pozycję w tablicy.
#include
#include
#include
void main(void)
{
clrscr();
const WymiarMax = 200;
int iLicznik;
int iRozmiarTablicy;
int aiTablica[WymiarMax];
int *paiTablica = aiTablica;
cout << "Podaj rozmiar tablicy: ";
cin >> iRozmiarTablicy;
cout << "Wprowadz kolejne elementy tablicy: ";
for (iLicznik = 0; iLicznik < iRozmiarTablicy; iLicznik ++)
{
cin >> * (paiTablica + iLicznik);
}
cout << "Oto kolejne elementy tablicy";
for (iLicznik = 0; iLicznik < iRozmiarTablicy; iLicznik ++)
{
cout << setw)8 << * (paiTablica + iLicznik);
}
cout< for (iLicznik = 0; iLicznik < iRozmiarTablicy; iLicznik ++) { if (* (paiTablica + iLicznik) > 0) { cout << "Dodatni element: " << * (paiTablica + iLicznik) << "na pozycji" << iLicznik+1 << endl; iLicznik++; } } cout << "Liczba dodatnich elementów: " << iLicznik; getch(); return 0; }