在 C 语言中,struct time 并不是一个像 int 或 float 那样的内置关键字,它通常是一个用户自定义的结构体,用于表示时间,这个结构体的目的是将小时、分钟、秒等相关的数据项组合成一个单一的、有意义的实体。

下面我将从以下几个方面为你详细解释:
- 为什么需要
struct time? - 如何定义
struct time? - 如何使用
struct time? - 标准库中的
struct tm - 一个完整的示例
- 进阶:函数和指针
为什么需要 struct time?
在 C 语言中,如果我们要表示一个时间点,"14 时 30 分 45 秒",最简单的方式是使用三个独立的变量:
int hour = 14; int minute = 30; int second = 45;
这样做有几个明显的缺点:
- 数据不相关:这三个变量在逻辑上是相关的,但在代码中它们是独立的,很容易被错误地修改或传递。
- 传递不便:如果你想将一个时间点传递给一个函数,你必须传递三个参数。
- 管理困难:如果程序中需要管理多个时间点(比如闹钟列表),每个都需要三个变量,代码会变得非常混乱。
使用 struct 可以完美地解决这些问题,它将相关的数据项打包到一个单元中,使代码更有组织性、更安全、更易于管理。

如何定义 struct time?
你可以使用 struct 关键字来定义自己的时间结构体,最常见的定义方式如下:
// 定义一个名为 TimeStruct 的结构体
struct TimeStruct {
int hour; // 小时 (0-23)
int minute; // 分钟 (0-59)
int second; // 秒 (0-59)
};
// 也可以使用 typedef 创建一个别名,这样就不需要每次都写 struct
typedef struct {
int hour;
int minute;
int second;
} Time; // 使用 Time 作为类型名,更简洁
typedef 的好处:
使用 typedef 后,你可以像使用基本类型一样使用 Time。
Time t1; // 声明一个 Time 类型的变量 t1
而不需要每次都写 struct TimeStruct t1;。
如何使用 struct time?
定义好结构体后,我们就可以像使用普通变量一样使用它了。

a. 声明和初始化
#include <stdio.h>
// 使用 typedef 的定义
typedef struct {
int hour;
int minute;
int second;
} Time;
int main() {
// 声明并初始化
Time now = {14, 30, 45};
// 先声明,后逐个赋值
Time alarm;
alarm.hour = 7;
alarm.minute = 0;
alarm.second = 0;
return 0;
}
b. 访问成员
使用点操作符 来访问结构体内部的成员。
Time now = {14, 30, 45};
printf("当前时间: %02d:%02d:%02d\n", now.hour, now.minute, now.second);
// 修改成员的值
now.second++;
if (now.second >= 60) {
now.second = 0;
now.minute++;
if (now.minute >= 60) {
now.minute = 0;
now.hour++;
if (now.hour >= 24) {
now.hour = 0;
}
}
}
printf("一秒后的时间: %02d:%02d:%02d\n", now.hour, now.minute, now.second);
输出:
当前时间: 14:30:45
一秒后的时间: 14:30:46
注意:%02d 是一个格式化说明符,0 表示用 0 填充,2 表示最小宽度为2,这样可以保证输出像 09:05:03 而不是 9:5:3。
标准库中的 struct tm
虽然你可以自己定义 struct time,但在实际的 C 语言编程中,处理日期和时间时,更常见的是使用标准库 <time.h> 中提供的 struct tm。
struct tm 是一个更通用的结构,它包含了日期和时间信息。
#include <time.h>
struct tm {
int tm_sec; // 秒 (0-59)
int tm_min; // 分钟 (0-59)
int tm_hour; // 小时 (0-23)
int tm_mday; // 一月中的第几天 (1-31)
int tm_mon; // 月份 (0-11, 0代表一月)
int tm_year; // 年份 (从1900年开始)
int tm_wday; // 一周中的第几天 (0-6, 0代表周日)
int tm_yday; // 一年中的第几天 (0-365)
int tm_isdst; // 夏令时标志
};
如何使用 struct tm?
通常你不会手动创建和填充 struct tm,而是使用标准库函数来获取当前时间或格式化时间。
#include <stdio.h>
#include <time.h> // 必须包含此头文件
int main() {
// 1. 声明一个 struct tm 变量
struct tm *time_info;
// 2. 获取当前时间
time_t raw_time;
time(&raw_time); // 获取当前时间的 Unix 时间戳
// 3. 将时间戳转换为本地时间的 tm 结构
time_info = localtime(&raw_time);
// 4. 访问并打印结构中的成员
printf("当前年份: %d\n", time_info->tm_year + 1900); // 年份需要加1900
printf("当前月份: %d\n", time_info->tm_mon + 1); // 月份需要加1
printf("当前小时: %d\n", time_info->tm_hour);
printf("当前分钟: %d\n", time_info->tm_min);
printf("当前秒: %d\n", time_info->tm_sec);
return 0;
}
输出示例:
当前年份: 2025
当前月份: 10
当前小时: 15
当前分钟: 30
当前秒: 45
注意:
localtime()返回一个指向struct tm的指针,所以我们使用->操作符来访问成员。tm_year是从1900开始的偏移量,所以实际年份需要+1900。tm_mon是从0开始的(0代表一月),所以实际月份需要+1。
一个完整的自定义 struct time 示例
这个例子展示了如何创建一个结构体,并通过函数来操作它。
#include <stdio.h>
// 1. 定义结构体
typedef struct {
int hour;
int minute;
int second;
} Time;
// 2. 函数声明
void setTime(Time *t, int h, int m, int s);
void printTime(const Time *t);
void addSecond(Time *t);
int main() {
Time myTime;
// 3. 使用函数设置时间
setTime(&myTime, 23, 59, 58);
printf("初始时间: ");
printTime(&myTime);
// 4. 修改时间状态
addSecond(&myTime);
printf("加一秒后: ");
printTime(&myTime);
addSecond(&myTime);
printf("再加一秒后: ");
printTime(&myTime);
return 0;
}
// 5. 函数定义
// 通过指针修改结构体内容
void setTime(Time *t, int h, int m, int s) {
t->hour = h;
t->minute = m;
t->second = s;
}
// 通过指针读取结构体内容,const 确保函数不会修改它
void printTime(const Time *t) {
printf("%02d:%02d:%02d\n", t->hour, t->minute, t->second);
}
// 通过指针修改结构体内容,实现时间递增
void addSecond(Time *t) {
t->second++;
if (t->second >= 60) {
t->second = 0;
t->minute++;
if (t->minute >= 60) {
t->minute = 0;
t->hour++;
if (t->hour >= 24) {
t->hour = 0;
}
}
}
}
输出:
初始时间: 23:59:58
加一秒后: 23:59:59
再加一秒后: 00:00:00
进阶:函数和指针
在 C 语言中,结构体通常通过指针传递给函数,主要有两个原因:
- 效率:结构体可能很大(比如包含很多成员),如果按值传递(直接传递结构体),整个结构体都会被复制一遍,这会消耗大量的时间和内存,传递指针只需要复制一个内存地址,效率高得多。
- 修改:如果你想在函数内部修改原始结构体的内容,你必须传递指针,在 C 语言中,函数参数是按值传递的,函数内部无法直接修改外部变量的值,除非你传递该变量的地址(即指针)。
- 按值传递(不推荐用于大型结构体):
void printTime(Time t);// 会创建一个副本 - 按指针传递(推荐):
void printTime(const Time *t);// 只传递地址,const保证函数不会意外修改它
| 特性 | 自定义 struct time |
标准 struct tm |
|---|---|---|
| 来源 | 用户自己定义 | C标准库 <time.h> 提供 |
| 用途 | 学习结构体概念,或用于非常简单的时间表示 | 处理复杂的日期和时间,格式化输入输出 |
| 成员 | 可自定义,如 hour, minute, second |
成员固定,包含年、月、日、时、分、秒、星期等 |
| 操作 | 需要自己编写函数来增加时间、比较时间等 | 标准库提供了丰富的函数(如 localtime, mktime, strftime) |
| 推荐场景 | 初学者学习,或项目中时间逻辑非常简单且固定 | 实际生产环境中处理所有与时间相关的任务 |
对于初学者来说,自己定义 struct time 是理解 C 语言结构体概念的绝佳方式,而在实际开发中,请务必优先使用标准库中的 struct tm 和相关函数,因为它们更强大、更可靠,并且考虑了各种边界情况(如闰年、夏令时等)。
