指针函数是一个函数,只是函数返回的是一个指针,也就是一个地址;
第一章 举例
struct tm
是标准 C 的 time.h
头文件中定义的一个结构体,用于存储分解后的时间数据。它将时间划分为年、月、日、小时、分钟、秒等字段,便于操作和格式化。
struct tm {int tm_sec; // 秒(0-60,允许闰秒)int tm_min; // 分(0-59)int tm_hour; // 小时(0-23)int tm_mday; // 一个月中的日期(1-31)int tm_mon; // 月份(0-11,0表示1月,11表示12月)int tm_year; // 自1900年起的年份(比如2024年表示为124)int tm_wday; // 一周中的第几天(0-6,0表示周日,6表示周六)int tm_yday; // 一年中的第几天(0-365,0表示1月1日)int tm_isdst; // 夏令时标志(>0 表示夏令时,0 表示非夏令时,<0 表示未知)
};
1.1 获取当前时间并且分解
#include <stdio.h>
#include <time.h>int main() {time_t current_time;struct tm *local_time;// 获取当前时间time(¤t_time);// 将时间转换为本地时间local_time = localtime(¤t_time);// 打印分解后的时间printf("Year: %d\n", local_time->tm_year + 1900);printf("Month: %d\n", local_time->tm_mon + 1);printf("Day: %d\n", local_time->tm_mday);printf("Hour: %d\n", local_time->tm_hour);printf("Minute: %d\n", local_time->tm_min);printf("Second: %d\n", local_time->tm_sec);return 0;
}
Year: 2024
Month: 12
Day: 12
Hour: 22
Minute: 8
Second: 3Process finished with exit code 0
第二章 函数指针的形式
struct tm *func_p(void){
return 堆空间地址;
}
2.1 返回静态变量的指定
#include <stdio.h>
#include <time.h>// 定义函数,返回静态变量的地址
struct tm *func_p(void) {static struct tm static_time; // 定义静态变量// 设置静态变量的值为当前本地时间time_t current_time;time(¤t_time);static_time = *localtime(¤t_time);return &static_time; // 返回静态变量的地址
}int main() {// 调用函数,获取静态变量地址struct tm *time_ptr = func_p();// 打印分解后的时间printf("Year: %d\n", time_ptr->tm_year + 1900);printf("Month: %d\n", time_ptr->tm_mon + 1);printf("Day: %d\n", time_ptr->tm_mday);printf("Hour: %d\n", time_ptr->tm_hour);printf("Minute: %d\n", time_ptr->tm_min);printf("Second: %d\n", time_ptr->tm_sec);return 0;
}
Year: 2024
Month: 12
Day: 12
Hour: 22
Minute: 12
Second: 55
2.2 返回堆空间的地址
#include <stdio.h>
#include <time.h>
#include <stdlib.h> // 用于 malloc 和 free// 定义函数,返回堆空间地址
struct tm *func_p(void) {// 动态分配 struct tm 空间struct tm *heap_time = (struct tm *)malloc(sizeof(struct tm));if (heap_time == NULL) {fprintf(stderr, "Memory allocation failed\n");return NULL; // 如果分配失败,返回 NULL}// 获取当前时间并填充到分配的空间time_t current_time;time(¤t_time);*heap_time = *localtime(¤t_time);return heap_time; // 返回分配的堆空间地址
}int main() {// 调用函数,获取堆空间地址struct tm *time_ptr = func_p();if (time_ptr == NULL) {return 1; // 内存分配失败时退出}// 打印分解后的时间printf("Year: %d\n", time_ptr->tm_year + 1900);printf("Month: %d\n", time_ptr->tm_mon + 1);printf("Day: %d\n", time_ptr->tm_mday);printf("Hour: %d\n", time_ptr->tm_hour);printf("Minute: %d\n", time_ptr->tm_min);printf("Second: %d\n", time_ptr->tm_sec);// 释放动态分配的内存free(time_ptr);time_ptr = NULL;return 0;
}
Year: 2024
Month: 12
Day: 12
Hour: 22
Minute: 14
Second: 44
2.3 返回全局变量的地址(不推荐)
#include <stdio.h>
#include <time.h>// 定义全局变量
struct tm global_time;// 定义函数,返回全局变量地址
struct tm *func_p(void) {// 获取当前时间并填充到全局变量time_t current_time;time(¤t_time);global_time = *localtime(¤t_time);return &global_time; // 返回全局变量地址
}int main() {// 调用函数,获取全局变量地址struct tm *time_ptr = func_p();// 打印分解后的时间printf("Year: %d\n", time_ptr->tm_year + 1900);printf("Month: %d\n", time_ptr->tm_mon + 1);printf("Day: %d\n", time_ptr->tm_mday);printf("Hour: %d\n", time_ptr->tm_hour);printf("Minute: %d\n", time_ptr->tm_min);printf("Second: %d\n", time_ptr->tm_sec);return 0;
}
Year: 2024
Month: 12
Day: 12
Hour: 22
Minute: 18
Second: 26
第三章 函数指针返回栈地址(错误示范)
#include <stdio.h>struct tm* func_p(void) {struct tm local_time; // 局部变量// 假设我们想填充这个结构体local_time.tm_year = 2024 - 1900;local_time.tm_mon = 11; // 12月(0-11)local_time.tm_mday = 31;local_time.tm_hour = 23;local_time.tm_min = 59;local_time.tm_sec = 59;// 错误地返回局部变量的地址return &local_time; // 返回栈地址(不安全)
}int main() {struct tm* time_ptr = func_p(); // 获取栈地址printf("Year: %d\n", time_ptr->tm_year + 1900);printf("Month: %d\n", time_ptr->tm_mon + 1);printf("Day: %d\n", time_ptr->tm_mday);return 0;
}
main.c:4:15: error: storage size of 'local_time' isn't known
struct tm local_time; // 局部变量
^~~~~~~~~~
E:\Mytest\test20241203\demo1\main.c: In function 'main':
E:\Mytest\test20241203\demo1\main.c:20:34: error: dereferencing pointer to incomplete type 'struct tm'
printf("Year: %d\n", time_ptr->tm_year + 1900);
^~
mingw32-make.exe[3]: *** [CMakeFiles/demo1.dir/main.c.obj] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/demo1.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles/demo1.dir/rule] Error 2
mingw32-make.exe: *** [demo1] Error 2