Menu
Coddy logo textTech

Powtórzenie: wskaźniki void

Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 49 z 61.

void* to sposób języka C na powiedzenie: „wskaźnik na coś, ale nie powiem ci na co”. Może przechowywać adres dowolnego typu danych: int, float, struktury lub czegokolwiek innego. Dzięki temu stanowi podstawę do pisania generycznego kodu w C.

Jest jednak pewien haczyk: nie możesz bezpośrednio dereferencjonować void*. Kompilator nie wie, ile bajtów odczytać ani jak je zinterpretować. Aby użyć danych, musisz rzutować wskaźnik z powrotem na właściwy typ:

void print_int(void* data) {
    int* p = (int*)data;
    printf("%d\n", *p);
}

int main() {
    int x = 42;
    print_int(&x);
    return 0;
}

Ta elastyczność wiąże się z odpowiedzialnością. Jeśli rzutujesz wskaźnik na niewłaściwy typ, kompilator cię przed tym nie powstrzyma, ale twój program zwróci śmieciowe dane lub ulegnie awarii. Dlatego funkcje generyczne często łączą void* ze wskaźnikiem typu (na przykład enumem lub flagą), aby funkcja wiedziała, jak poprawnie zinterpretować dane.

W nadchodzących lekcjach użyjesz void* do tworzenia kontenerów, które mogą przechowywać dane dowolnego typu, umożliwiając tworzenie naprawdę wielokrotnego użytku struktur danych.

challenge icon

Wyzwanie

Łatwy

Napisz funkcję o nazwie print_value, która przyjmuje dwa parametry: wskaźnik void* do danych oraz flagę typu int. Funkcja powinna interpretować i wyświetlać dane na podstawie flagi typu:

  • Jeśli flaga typu ma wartość 0, rzutuj wskaźnik na int* i wyświetl wartość całkowitą
  • Jeśli flaga typu ma wartość 1, rzutuj wskaźnik na float* i wyświetl wartość zmiennoprzecinkową z dokładnością do 2 miejsc po przecinku

Twój program otrzyma dwa dane wejściowe:

  1. Flagę typu (0 dla liczby całkowitej, 1 dla liczby zmiennoprzecinkowej)
  2. Wartość liczbową

Na podstawie flagi typu zapisz wartość w zmiennej odpowiedniego typu, a następnie wywołaj funkcję print_value, przekazując wskaźnik do tej zmiennej oraz flagę typu.

Przykładowe wyjście, gdy dane wejściowe to 0 i 42:

42

Przykładowe wyjście, gdy dane wejściowe to 1 i 3.14:

3.14

Przykładowe wyjście, gdy dane wejściowe to 0 i -17:

-17

Przykładowe wyjście, gdy dane wejściowe to 1 i 99.5:

99.50

Spróbuj swoich sił

#include <stdio.h>

// TODO: Napisz tutaj swoją funkcję print_value


int main() {
    int type_flag;
    scanf("%d", &type_flag);
    
    if (type_flag == 0) {
        int int_value;
        scanf("%d", &int_value);
        
        // TODO: Wywołaj print_value ze wskaźnikiem do int_value i flagą typu
        
    } else if (type_flag == 1) {
        float float_value;
        scanf("%f", &float_value);
        
        // TODO: Wywołaj print_value ze wskaźnikiem do float_value i flagą typu
        
    }
    
    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C online