Структуры как объекты
Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 6 из 61.
В объектно-ориентированных языках объект — это сущность, которая объединяет данные (состояние) с функциями, работающими с этими данными (методами). В языке C нет встроенных объектов, но мы можем реализовать ту же концепцию, используя структуры (structs) и функции.
Представьте себе структуру (struct) как «данные» объекта. Она хранит состояние — значения, которые определяют, чем объект является в данный момент:
typedef struct {
int value;
} Counter;
Эта структура Counter представляет собой сущность с единственным состоянием: её текущим значением. Чтобы наделить её поведением, мы пишем функции, которые принимают структуру в качестве параметра:
void counter_increment(Counter *c) {
c->value++;
}
int counter_get(Counter *c) {
return c->value;
}
Эти функции действуют как методы — они работают непосредственно с данными Counter. Передавая структуру в функции, мы имитируем то, что другие языки делают автоматически при вызове counter.increment().
int main() {
Counter my_counter = {0};
counter_increment(&my_counter);
printf("%d\n", counter_get(&my_counter)); // Выводит: 1
return 0;
}
Соглашение об именовании typename_action (например, counter_increment) помогает организовать ваш код и проясняет, к какой структуре относится функция. Этот паттерн является основой объектно-ориентированного программирования на языке C.
Задание
ЛегкоДавайте создадим простой модуль Counter, который рассматривает структуру как объект с поведением. Вы организуете свой код в трех файлах, чтобы попрактиковаться в шаблоне объединения данных с функциями, которые ими управляют.
Вы создадите три файла:
counter.h: Ваш заголовочный файл, объявляющий структуруCounterс единственным членомint value. Также объявите две функции, которые действуют как «методы» для счетчика:counter_increment(принимает указатель на Counter и увеличивает его значение на 1) иcounter_get(принимает указатель на Counter и возвращает его текущее значение). Используйте include guards с символомCOUNTER_H.counter.c: Ваш исходный файл, реализующий обе функции. Не забудьте включить ваш заголовочный файл.main.c: Ваш основной файл, который создает Counter, выполняет над ним операции и отображает результаты.
Вы получите два целых числа на вход: начальное значение для вашего счетчика и количество раз, которое его нужно увеличить.
В вашем основном файле инициализируйте Counter начальным значением, затем вызовите counter_increment указанное количество раз. Наконец, используйте counter_get, чтобы получить и вывести конечное значение.
Выведите результат в следующем формате:
Final value: {result}Например, при начальном значении 5 и 3 инкрементах вывод будет следующим:
Final value: 8Шпаргалка
В языке C мы можем имитировать объектно-ориентированное программирование, комбинируя структуры (данные) с функциями (поведением), которые работают с этими структурами.
Определите структуру для хранения состояния:
typedef struct {
int value;
} Counter;
Создайте функции, которые действуют как «методы», принимая структуру в качестве параметра:
void counter_increment(Counter *c) {
c->value++;
}
int counter_get(Counter *c) {
return c->value;
}
Используйте структуру и функции вместе:
Counter my_counter = {0};
counter_increment(&my_counter);
printf("%d\n", counter_get(&my_counter)); // Prints: 1
Соглашение об именовании typename_action (например, counter_increment) помогает организовать код и проясняет, с какой структурой работает функция.
Попробуйте сами
#include <stdio.h>
#include "counter.h"
int main() {
// Считать входные данные
int starting_value;
int num_increments;
scanf("%d", &starting_value);
scanf("%d", &num_increments);
// TODO: Создать Counter и инициализировать его значением starting_value
// TODO: Вызвать counter_increment указанное количество раз
// TODO: Использовать counter_get для получения итогового значения и вывести его
// Формат вывода: "Final value: {result}"
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация круга