Исходные файлы
Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 3 из 61.
До сих пор мы размещали объявления функций в заголовочных файлах, но сам код функции (определение) находился в основном файле. Следующим шагом в модульном программировании является перенос этих определений в их собственные исходные файлы (.c файлы).
Это создает чистую структуру из трех частей: заголовочный файл объявляет функции, отдельный исходный файл определяет их, а main просто использует их. Вот как это выглядит:
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif
// math_utils.c
#include "math_utils.h"
int add(int a, int b) {
return a + b;
}
// main.c
#include <stdio.h>
#include "math_utils.h"
int main() {
printf("%d\n", add(5, 3));
return 0;
}
Обратите внимание, что math_utils.c включает собственный заголовочный файл. Это гарантирует, что определение функции соответствует объявлению — если они не совпадают, компилятор обнаружит ошибку. Основному файлу нужно только включить заголовочный файл, чтобы использовать функцию; ему не нужно знать, как add работает внутри.
Это разделение скрывает детали реализации и позволяет изменять логику функций, не затрагивая файлы, которые используют эти функции.
Задание
ЛегкоДавайте создадим простую математическую утилиту, организовав ваш код в правильную трехфайловую структуру: заголовочный файл для объявлений, исходный файл для реализаций и основной файл, который их использует.
Вы создадите три файла:
math_ops.h: Ваш заголовочный файл, содержащий объявления функций для двух операций:multiplyиsubtract. Обе функции принимают два целых числа и возвращают целое число. Не забудьте включить защиту от повторного включения (guards), используя символMATH_OPS_H.math_ops.c: Ваш исходный файл, содержащий фактическую реализацию функцийmultiplyиsubtract. Этот файл должен включать собственный заголовочный файл, чтобы гарантировать соответствие объявлений определениям.main.c: Ваш основной файл, который включает заголовочный файл и использует обе функции для выполнения вычислений.
Функция multiply должна возвращать произведение двух целых чисел, а subtract должна возвращать разность первого и второго целых чисел.
Вы получите на вход два целых числа: a и b.
В вашей функции main выведите результаты обеих операций на отдельных строках:
Product: {result of multiply}
Difference: {result of subtract}Например, при входных данных 8 и 3 вывод будет следующим:
Product: 24
Difference: 5Шпаргалка
Определения функций можно перенести из основного файла в отдельные исходные файлы (файлы .c), создав трехчастную модульную структуру:
- Заголовочный файл (
.h): Содержит объявления функций - Исходный файл (
.c): Содержит определения функций - Основной файл (
main.c): Использует функции
Пример структуры:
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif
// math_utils.c
#include "math_utils.h"
int add(int a, int b) {
return a + b;
}
// main.c
#include <stdio.h>
#include "math_utils.h"
int main() {
printf("%d\n", add(5, 3));
return 0;
}
Исходный файл (.c) должен включать собственный заголовочный файл, чтобы гарантировать соответствие определения функции её объявлению. Основному файлу достаточно включить только заголовочный файл для использования функций, что позволяет скрыть детали реализации.
Попробуйте сами
#include <stdio.h>
#include "math_ops.h"
int main() {
int a, b;
scanf("%d", &a);
scanf("%d", &b);
// TODO: Вызовите функцию умножения с a и b, сохраните результат
// TODO: Вызовите функцию вычитания с a и b, сохраните результат
// TODO: Выведите результаты в формате:
// Product: {результат умножения}
// Difference: {результат вычитания}
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация круга