Menu
Coddy logo textTech

Повторение: указатели void

Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 49 из 61.

void* — это способ языка C сказать: «указатель на что-то, но я не скажу на что». Он может хранить адрес любого типа данных — int, float, структуры или чего-либо еще. Это делает его основой для написания обобщенного кода на C.

Подвох в том, что вы не можете разыменовать void* напрямую. Компилятор не знает, сколько байт нужно прочитать и как их интерпретировать. Чтобы использовать данные, вы должны привести их обратно к правильному типу:

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

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

Эта гибкость сопряжена с ответственностью. Если вы выполните приведение к неправильному типу, компилятор вас не остановит, но ваша программа выдаст мусор или завершится с ошибкой. Вот почему обобщенные функции часто используют void* в паре с индикатором типа (например, enum или флагом), чтобы функция знала, как правильно интерпретировать данные.

В следующих уроках вы будете использовать void* для создания контейнеров, которые могут хранить любые типы данных, что позволит создавать по-настоящему переиспользуемые структуры данных.

challenge icon

Задание

Легко

Напишите функцию с именем print_value, которая принимает два параметра: указатель void* на данные и флаг типа int. Функция должна интерпретировать и выводить данные на основе флага типа:

  • Если флаг типа равен 0, приведите указатель к типу int* и выведите целое число.
  • Если флаг типа равен 1, приведите указатель к типу float* и выведите число с плавающей запятой с 2 знаками после запятой.

Ваша программа получит два входных значения:

  1. Флаг типа (0 для целого числа, 1 для числа с плавающей запятой)
  2. Числовое значение

В зависимости от флага типа, сохраните значение в переменную соответствующего типа, затем вызовите print_value с указателем на эту переменную и флагом типа.

Пример вывода, когда входные данные 0 и 42:

42

Пример вывода, когда входные данные 1 и 3.14:

3.14

Пример вывода, когда входные данные 0 и -17:

-17

Пример вывода, когда входные данные 1 и 99.5:

99.50

Шпаргалка

void* — это универсальный указатель, который может хранить адрес любого типа данных. Он обеспечивает гибкость для написания обобщенного кода на языке C.

Вы не можете разыменовать void* напрямую — сначала вы должны привести его к правильному типу:

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

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

Обобщенные функции часто используют void* в паре с индикатором типа (например, перечислением или флагом), чтобы знать, как правильно интерпретировать данные. Приведение к неправильному типу может привести к неопределенному поведению или сбоям.

Попробуйте сами

#include <stdio.h>

// TODO: Напишите здесь вашу функцию print_value


int main() {
    int type_flag;
    scanf("%d", &type_flag);
    
    if (type_flag == 0) {
        int int_value;
        scanf("%d", &int_value);
        
        // TODO: Вызовите print_value с указателем на int_value и флагом типа
        
    } else if (type_flag == 1) {
        float float_value;
        scanf("%f", &float_value);
        
        // TODO: Вызовите print_value с указателем на float_value и флагом типа
        
    }
    
    return 0;
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Object Oriented Programming