第 1 步:定义车辆的基本结构
我们需要一个 Vehicle 结构体来存储一辆车的所有属性,这是 C 语言中组织复杂数据的常用方法。

(图片来源网络,侵删)
vehicle.h (头文件)
将结构体定义放在头文件中是一个好习惯,方便其他代码文件包含和使用它。
#ifndef VEHICLE_H
#define VEHICLE_H
#include <stdio.h>
#include <string.h> // 用于 strcpy
// 定义车辆类型枚举,增加代码可读性
typedef enum {
CAR,
TRUCK,
MOTORCYCLE,
BUS
} VehicleType;
// 定义车辆结构体
typedef struct {
int id; // 车辆唯一ID
char make[50]; // 品牌 (e.g., "Toyota")
char model[50]; // 型号 (e.g., "Camry")
int year; // 年份
VehicleType type; // 车辆类型
float mileage; // 里程数 (公里)
char license_plate[20]; // 车牌号
} Vehicle;
#endif // VEHICLE_H
解释:
#ifndef ... #define ... #endif是一个宏,防止头文件被重复包含。typedef enum定义了一个名为VehicleType的枚举类型,让我们可以用CAR,TRUCK等有意义的单词来代替数字。typedef struct定义了一个名为Vehicle的结构体类型,它包含了描述一辆车所需的各种数据。char make[50]这样的字符数组用于存储字符串。
第 2 步:创建车辆操作的函数
我们为 Vehicle 结构体创建一些基本操作函数,比如创建、打印、更新等,这些函数通常放在一个 .c 文件中。

(图片来源网络,侵删)
vehicle.c (实现文件)
#include "vehicle.h"
/**
* @brief 创建并初始化一个新的车辆
*
* @param id 车辆ID
* @param make 品牌
* @param model 型号
* @param year 年份
* @param type 车辆类型
* @param mileage 里程
* @param plate 车牌号
* @return Vehicle 返回一个初始化好的车辆结构体
*/
Vehicle createVehicle(int id, const char* make, const char* model, int year,
VehicleType type, float mileage, const char* plate) {
Vehicle v;
v.id = id;
strcpy(v.make, make);
strcpy(v.model, model);
v.year = year;
v.type = type;
v.mileage = mileage;
strcpy(v.license_plate, plate);
return v;
}
/**
* @brief 打印车辆信息
*
* @param v 要打印的车辆
*/
void printVehicle(const Vehicle* v) {
// 使用指针接收结构体,避免大结构体拷贝,效率更高
printf("--- Vehicle Details ---\n");
printf("ID: %d\n", v->id);
printf("Make: %s\n", v->make);
printf("Model: %s\n", v->model);
printf("Year: %d\n", v->year);
// 根据枚举值打印对应的字符串
switch (v->type) {
case CAR: printf("Type: Car\n"); break;
case TRUCK: printf("Type: Truck\n"); break;
case MOTORCYCLE: printf("Type: Motorcycle\n"); break;
case BUS: printf("Type: Bus\n"); break;
default: printf("Type: Unknown\n");
}
printf("Mileage: %.2f km\n", v->mileage);
printf("License Plate: %s\n", v->license_plate);
printf("-----------------------\n\n");
}
/**
* @brief 更新车辆的里程数
*
* @param v 指向要更新的车辆的指针
* @param new_mileage 新的里程数
*/
void updateMileage(Vehicle* v, float new_mileage) {
v->mileage = new_mileage;
printf("Mileage updated to %.2f km for vehicle %d.\n\n", new_mileage, v->id);
}
解释:
createVehicle: 这是一个工厂函数,用于方便地创建一个Vehicle实例。printVehicle: 接收一个Vehicle的指针const Vehicle* v,使用指针可以避免复制整个结构体,这在结构体很大时能显著提高性能。->操作符用于通过指针访问结构体的成员。updateMileage: 同样使用指针,以便直接修改原始结构体中的mileage值。
第 3 步:主程序 - 使用车辆
现在我们创建一个 main.c 文件来使用我们定义的 Vehicle 结构体和函数。
main.c

(图片来源网络,侵删)
#include "vehicle.h"
#include <stdio.h>
int main() {
// 1. 创建两辆车
Vehicle myCar = createVehicle(101, "Tesla", "Model 3", 2025, CAR, 15000.5, "京A12345");
Vehicle myTruck = createVehicle(102, "Ford", "F-150", 2025, TRUCK, 45000.0, "沪B67890");
// 2. 打印车辆信息
printf("Initial Vehicle Information:\n");
printVehicle(&myCar);
printVehicle(&myTruck);
// 3. 更新其中一辆车的里程
updateMileage(&myCar, 15500.75);
// 4. 再次打印更新后的信息
printf("Vehicle Information After Update:\n");
printVehicle(&myCar);
return 0;
}
如何编译和运行: 你需要将这三个文件放在同一个目录下,然后使用 gcc 进行编译:
# 编译所有 .c 文件,并生成一个名为 vehicle_program 的可执行文件 gcc main.c vehicle.c -o vehicle_program # 运行程序 ./vehicle_program
预期输出:
Initial Vehicle Information:
--- Vehicle Details ---
ID: 101
Make: Tesla
Model: Model 3
Year: 2025
Type: Car
Mileage: 15000.50 km
License Plate: 京A12345
-----------------------
--- Vehicle Details ---
ID: 102
Make: Ford
Model: F-150
Year: 2025
Type: Truck
Mileage: 45000.00 km
License Plate: 沪B67890
-----------------------
Mileage updated to 15500.75 km for vehicle 101.
Vehicle Information After Update:
--- Vehicle Details ---
ID: 101
Make: Tesla
Model: Model 3
Year: 2025
Type: Car
Mileage: 15500.75 km
License Plate: 京A12345
-----------------------
第 4 步:进阶 - 将车辆信息保存到文件
在实际应用中,我们经常需要将数据持久化存储,下面我们增加一个功能,将车辆信息保存到文本文件,并从文件中读取。
在 vehicle.c 中添加新函数:
// ... (之前的函数保持不变)
/**
* @brief 将车辆信息写入文件
*
* @param v 要写入的车辆
* @param filename 文件名
*/
void saveVehicleToFile(const Vehicle* v, const char* filename) {
FILE *file = fopen(filename, "w"); // "w" 表示写入模式,如果文件不存在则创建
if (file == NULL) {
perror("Error opening file for writing");
return;
}
// 将结构体成员以文本格式写入文件
fprintf(file, "%d\n", v->id);
fprintf(file, "%s\n", v->make);
fprintf(file, "%s\n", v->model);
fprintf(file, "%d\n", v->year);
fprintf(file, "%d\n", v->type); // 枚举值作为整数存储
fprintf(file, "%.2f\n", v->mileage);
fprintf(file, "%s\n", v->license_plate);
fclose(file);
printf("Vehicle %d saved to %s\n\n", v->id, filename);
}
/**
* @brief 从文件中读取车辆信息
*
* @param filename 文件名
* @return Vehicle 返回一个从文件读取并初始化的车辆
*/
Vehicle loadVehicleFromFile(const char* filename) {
Vehicle v;
FILE *file = fopen(filename, "r"); // "r" 表示读取模式
if (file == NULL) {
perror("Error opening file for reading");
// 返回一个空的或默认的车辆
return createVehicle(0, "", "", 0, CAR, 0.0, "");
}
// 从文件中读取数据并填充结构体
fscanf(file, "%d", &v.id);
fscanf(file, "%49s", v.make); // 使用 %49s 防止缓冲区溢出
fscanf(file, "%49s", v.model);
fscanf(file, "%d", &v.year);
fscanf(file, "%d", (int*)&v.type); // 读取整数并转换为枚举
fscanf(file, "%f", &v.mileage);
fscanf(file, "%19s", v.license_plate);
fclose(file);
printf("Vehicle %d loaded from %s\n\n", v.id, filename);
return v;
}
更新 main.c 来测试文件操作:
#include "vehicle.h"
#include <stdio.h>
int main() {
// 1. 创建一辆新车
Vehicle newCar = createVehicle(201, "BMW", "iX", 2025, CAR, 0.0, "粤C11111");
// 2. 将新车信息保存到文件
saveVehicleToFile(&newCar, "bmw_ix.txt");
// 3. 从文件中读取车辆信息
Vehicle loadedCar = loadVehicleFromFile("bmw_ix.txt");
// 4. 打印从文件加载的车辆信息,验证是否正确
printf("Vehicle Information Loaded from File:\n");
printVehicle(&loadedCar);
return 0;
}
编译和运行:
gcc main.c vehicle.c -o vehicle_program ./vehicle_program
预期输出:
Vehicle 201 saved to bmw_ix.txt
Vehicle 201 loaded from bmw_ix.txt
Vehicle Information Loaded from File:
--- Vehicle Details ---
ID: 201
Make: BMW
Model: iX
Year: 2025
Type: Car
Mileage: 0.00 km
License Plate: 粤C11111
-----------------------
你会在同一目录下看到一个名为 bmw_ix.txt 的文件,其内容如下:
201
BMW
iX
2025
0
0.00
粤C11111
这个完整的 C 语言 Vehicle 示例涵盖了:
- 结构体: 用于定义自定义数据类型
Vehicle。 - 枚举: 为车辆类型提供可读的常量。
- 函数: 封装对车辆的操作,如创建、打印、更新。
- 指针: 高效地传递和修改结构体数据。
- 文件 I/O: 将数据保存到文件和从文件读取,实现数据持久化。
这是一个非常经典和实用的 C 语言编程模式,可以作为构建更复杂数据系统(如库存管理、学生信息管理系统)的基础。
