Definicja
Typ tablicowy (ang. array type) w C/C++ reprezentuje kolekcję stałej liczby elementów tego samego typu, przechowywanych w ciągłym bloku pamięci. Dostęp do poszczególnych elementów uzyskuje się za pomocą nazwy tablicy i indeksu (numeru elementu, liczonego od 0).
Deklaracja i Inicjalizacja
Składnia deklaracji:
TypElementu NazwaTablicy[Rozmiar];
TypElementu: Typ danych, które będą przechowywane w tablicy (np. int, float, char, obiekt klasy).
NazwaTablicy: Identyfikator (nazwa) tablicy.
Rozmiar: Liczba całkowita (lub wyrażenie stałe czasu kompilacji) określająca liczbę elementów tablicy. Musi być znany w momencie kompilacji dla tablic statycznych (alokowanych na stosie lub w segmencie danych).
Przykłady deklaracji i inicjalizacji:
int wyniki[10];
float temperatury[5] = { 10.5f, 12.0f, 9.8f, 11.3f, 13.1f };
char litery[] = { 'a', 'b', 'c' };
int dane[100] = { 0 };
int czesciowe[5] = { 1, 2 };
char napis[20] = "Witaj";
char napis_auto[] = "Swiecie";
Dostęp do Elementów
Dostęp do elementu uzyskuje się przez podanie nazwy tablicy i indeksu w nawiasach kwadratowych []. Indeksy liczone są od 0 do Rozmiar-1.
temperatury[0] = 15.0f;
float druga_temp = temperatury[1];
std::cout << napis[4];
Uwaga: C++ (podobnie jak C) nie sprawdza automatycznie, czy indeks mieści się w granicach tablicy. Odwołanie się do elementu poza zakresem (np. wyniki[10] dla tablicy o rozmiarze 10) prowadzi do niezdefiniowanego zachowania (undefined behavior), co może skutkować awarią programu, uszkodzeniem danych lub trudnymi do wykrycia błędami.
Tablice Wielowymiarowe
Można tworzyć tablice tablic, czyli tablice wielowymiarowe.
int macierz[3][4];
int plansza[2][3] = {
{ 1, 2, 3 },
{ 4, 5, 6 }
};
int element = plansza[1][2];
W pamięci elementy tablicy wielowymiarowej są zazwyczaj przechowywane wierszami (row-major order).
Tablice a Wskaźniki
W C/C++ istnieje silny związek między tablicami a wskaźnikami:
- Nazwa tablicy (bez indeksu) w wielu kontekstach (np. przy przekazywaniu do funkcji, przypisaniu do wskaźnika) ulega niejawnej konwersji (decay) do wskaźnika na jej pierwszy element.
- Arytmetyka wskaźników pozwala na iterowanie po tablicy.
*(tablica + i) jest równoważne tablica[i].
int numery[5] = { 10, 20, 30, 40, 50 };
int* ptr = numery;
std::cout << *ptr;
std::cout << *(ptr + 2);
std::cout << ptr[2];
ptr++;
std::cout << *ptr;
Przy przekazywaniu tablicy do funkcji, zazwyczaj przekazywany jest tylko wskaźnik na jej pierwszy element. Funkcja traci informację o rozmiarze tablicy, dlatego rozmiar często trzeba przekazać jako dodatkowy argument.
void drukujTablice(int tab[], int rozmiar) {
for (int i = 0; i < rozmiar; ++i) {
std::cout << tab[i] << " ";
}
std::cout << std::endl;
}
Tablice Dynamiczne
Standardowe tablice C-style mają rozmiar ustalony w czasie kompilacji. Do tworzenia tablic o rozmiarze określanym w czasie działania programu używa się alokacji dynamicznej (operator new[] i delete[]) lub lepiej, kontenerów z Biblioteki Standardowej.
int rozmiar;
std::cin >> rozmiar;
double* dynamiczna_tablica = new double[rozmiar];
dynamiczna_tablica[0] = 1.0;
delete[] dynamiczna_tablica;
dynamiczna_tablica = nullptr;
Nowoczesne Alternatywy (C++)
W nowoczesnym C++ często preferuje się użycie kontenerów z Biblioteki Standardowej zamiast surowych tablic C-style, ponieważ zapewniają one większe bezpieczeństwo i wygodę:
std::vector: Dynamiczna tablica (rozmiar może się zmieniać w trakcie działania), automatycznie zarządza pamięcią, przechowuje informacje o swoim rozmiarze (size()), oferuje sprawdzanie granic (at()). Najczęściej używany zamiennik tablic dynamicznych.
std::array (od C++11): Kontener o stałym rozmiarze (określonym w czasie kompilacji), ale z interfejsem kontenera STL (metody size(), iteratory, itp.). Dobry zamiennik dla tablic statycznych C-style, gdy rozmiar jest znany i stały.
std::string: Specjalizowany kontener do przechowywania i manipulowania ciągami znaków, znacznie wygodniejszy i bezpieczniejszy niż tablice char w stylu C.
#include <vector>
#include <array>
#include <string>
#include <iostream>
std::vector<int> v = { 1, 2, 3 };
v.push_back(4);
std::cout << "Rozmiar vectora: " << v.size() << std::endl;
std::cout << "Element v[1] (at): " << v.at(1) << std::endl;
std::array<float, 3> arr = { 1.1f, 2.2f, 3.3f };
std::cout << "Rozmiar array: " << arr.size() << std::endl;
Przykłady Wykorzystania Tablic
- Przechowywanie serii danych pomiarowych (temperatury, wyniki testów).
- Implementacja struktur danych (np. stosu, kolejki na bazie tablicy).
- Reprezentacja macierzy w obliczeniach numerycznych.
- Przechowywanie planszy w grach (np. szachy, warcaby).
- Buforowanie danych (np. przy odczycie/zapisie plików).
- Przechowywanie ciągów znaków (tablice
char w C, choć std::string jest lepszy w C++).