C Academy · Lekcja

Wielokrotnego użytku typ wektora

Opakuje Pan/Pani rozmiar i pojemność.

Lekcja 3 z 413 kroki

Wielokrotnego użytku typ wektora to bezpłatna lekcja C Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C Academy zawiera 4 lekcji w sumie.

Od luźnego kodu do typu

Przekazywanie wskaźnika, liczby elementów i pojemności jako trzech osobnych zmiennych jest podatne na błędy.

Połączmy je w jeden struct: wielokrotnego użytku tablicę dynamiczną, często nazywaną wektorem. Łączy ona dane z informacjami potrzebnymi do zarządzania nimi.

Struktura wektora

Wektor potrzebuje trzech pól: wskaźnika do danych, liczby używanych elementów (len) oraz liczby elementów, które mieszczą się przed zmianą rozmiaru (cap).

typedef struct {
    int    *data;
    size_t  len;
    size_t  cap;
} Vec;

Inicjalizowanie wektora

Pusty wektor ma wskaźnik danych o wartości NULL oraz zerową długość i pojemność. Niewielka funkcja init jasno pokazuje intencję.

void vec_init(Vec *v) {
    v->data = NULL;
    v->len = 0;
    v->cap = 0;
}

Operacja push

vec_push dodaje jeden element na końcu. Jeśli wektor jest pełny, najpierw dwukrotnie zwiększa jego pojemność.

Zwraca 0 w przypadku powodzenia i -1 w przypadku niepowodzenia alokacji, dzięki czemu kod wywołujący może odpowiednio zareagować.

int vec_push(Vec *v, int value) {
    if (v->len == v->cap) {
        size_t nc = v->cap ? v->cap * 2 : 4;
        int *tmp = realloc(v->data, nc * sizeof(*v->data));
        if (!tmp) return -1;
        v->data = tmp;
        v->cap = nc;
    }
    v->data[v->len++] = value;
    return 0;
}

Odczytywanie elementów

Ponieważ len przechowuje liczbę używanych elementów, należy iterować od 0 do len - 1. Pojemność może być większa, ale te dodatkowe miejsca nie należą jeszcze do danych.

for (size_t i = 0; i < v->len; i++)
    printf("%d\n", v->data[i]);

Zwalnianie wektora

Wektor jest właścicielem swojego bufora na stercie, dlatego potrzebuje odpowiadającej mu funkcji czyszczącej. Po zwolnieniu pamięci należy wyzerować pola, aby struktura nie mogła zostać użyta nieprawidłowo.

void vec_free(Vec *v) {
    free(v->data);
    v->data = NULL;
    v->len = v->cap = 0;
}

Połączenie wszystkich elementów

Ten kompletny program tworzy wektor, dodaje do niego pięć wartości, wyświetla je, a następnie prawidłowo go zwalnia.

#include <stdio.h>
#include <stdlib.h>

typedef struct { int *data; size_t len, cap; } Vec;

int vec_push(Vec *v, int value) {
    if (v->len == v->cap) {
        size_t nc = v->cap ? v->cap * 2 : 4;
        int *tmp = realloc(v->data, nc * sizeof(*v->data));
        if (!tmp) return -1;
        v->data = tmp; v->cap = nc;
    }
    v->data[v->len++] = value;
    return 0;
}

int main(void) {
    Vec v = {0};
    for (int i = 0; i < 5; i++) vec_push(&v, i * 10);
    for (size_t i = 0; i < v.len; i++) printf("%d\n", v.data[i]);
    free(v.data);
    return 0;
}

Zerowanie za pomocą {0}

Zapis Vec v = {0}; ustawia wszystkie pola na zero, w tym wskaźnik danych na NULL.

To wygodny skrót, który przygotowuje wektor do użycia z vec_push bez wywoływania jawnej funkcji inicjalizującej.

Vec v = {0};      /* data=NULL, len=0, cap=0 */
vec_push(&v, 42);

Bezpieczna funkcja pomocnicza get

Indeksowanie poza len jest błędem. Niewielka funkcja dostępowa może sprawdzać zakres i sygnalizować błędy, poświęcając odrobinę szybkości na rzecz bezpieczeństwa.

int vec_get(const Vec *v, size_t i, int *out) {
    if (i >= v->len) return -1;   /* out of range */
    *out = v->data[i];
    return 0;
}

Dlaczego len i cap są osobne

cap określa, ile pamięci zaalokowano, a len — ile pamięci jest faktycznie używane.

Utrzymywanie zapasu pojemności sprawia, że większość operacji push nie wywołuje realloc. To rozdzielenie sprawia, że wektor jest jednocześnie szybki i elastyczny.

Uogólnianie typu

Ten wektor przechowuje wartości typu int. Aby przechowywać inne typy, można zmienić typ elementu albo użyć void * wraz z rozmiarem elementu.

Wzorzec — init, push, free — pozostaje taki sam niezależnie od przechowywanych danych.

typedef struct {
    double *data;
    size_t  len, cap;
} DVec;   /* same shape, different element type */

Szybkie sprawdzenie

Sprawdź, jak dobrze rozumieją Państwo typ wektora.

Podsumowanie

Wektor łączy wskaźnik danych, len i cap w jeden struct.

vec_push podwaja pojemność, gdy wektor jest pełny, vec_free zwalnia bufor i resetuje pola, a {0} poprawnie inicjalizuje strukturę. Ten wielokrotnego użytku wzorzec jest lepszy niż żonglowanie luźnymi zmiennymi. Dalej: poprawne zwalnianie pamięci i unikanie wycieków.

Bezpłatny start

Ucz się C dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
39
Lekcje
144

Często zadawane pytania

Czy lekcja „Wielokrotnego użytku typ wektora” jest bezpłatna?

Tak — pełny tekst „Wielokrotnego użytku typ wektora” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C Academy, przejdź na CoddyKit PRO. Kurs C Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wielokrotnego użytku typ wektora”?

Opakuje Pan/Pani rozmiar i pojemność. Ćwiczysz C Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C Academy?

Nie wymagamy żadnego doświadczenia. C Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Wielokrotnego użytku typ wektora”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C Academy?

Tak. Każda lekcja C Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Alokowanie tablicy
  2. Powiększanie za pomocą realloc
  3. Wielokrotnego użytku typ wektora
  4. Zwalnianie pamięci i unikanie wycieków
← Powrót do C Academy