小心C语言时间函数陷阱

在编写C语言的应用程序时,为了获取或者打印一些跟时间有关的信息,我们经常会使用到C语言自带的一 些时间函数,诸如:time、localtime、ctime、mktime和asctime等。但你可能没有注意到这里面含有一些有 趣的现象,先来看一个例子:

1 #include <stdio.h>
2 #include <time.h>
3
4 int main ()
5 {
6
7 time_t time_1, time_2;
8 struct tm *tm_1, *tm_2, *tm_3;
9 struct tm tm_4, tm_5;
10
11 printf("-------------------- PART I -------------------\n");
12
13 time_1 = time(NULL);
14 sleep(3);
15 time_2 = time(NULL);
16 printf("time1:%d time2:%d\n",time_1,time_2);
17
18 tm_1 = (struct tm*)localtime(&time_1);
19 tm_2 = (struct tm*)localtime(&time_2);
20 tm_3 = (struct tm*)localtime(&time_1);
21
22 printf("tm_1 ptr:%p tm_2 ptr:%p tm_3 ptr:%p\n",tm_1,tm_2,tm_3);
23 printf("asctime(tm_1):%s",asctime(tm_1));
24 printf("asctime(tm_2):%s",asctime(tm_2));
25 printf("asctime(tm_3):%s",asctime(tm_3));
26 }

在看这段代码的输出结果之前,先问大家两个问题:

 (1) 第22行,struct tm结构体 tm_1、tm_2 和tm_3的值有什么关系?

 (2) 第23-26行的输出结果中,tm_2的时间真的比tm_1晚3秒吗?

接下来 ,我们来看一下这段代码的输出结果:

-------------------- PART I -------------------

time1:1340256774 time2:1340256777

tm_1 ptr:0xfec6f48 tm_2 ptr:0xfec6f48 tm_3 ptr:0xfec6f48

asctime(tm_1):Thu Jun 21 01:32:54 2012

asctime(tm_2):Thu Jun 21 01:32:54 2012

asctime(tm_3):Thu Jun 21 01:32:54 2012

这里的打印结果是否跟你前面预想的一样呢?没错 ,第22行中的tm_1、tm_2和tm_3其实指向的是同一个地址。在localtime函数的实现中,采用了一个静态内部 struct tm结构体来存储对应的时间信息。每次对localtime函数的调用,都将会修改内部这个struct tm结构 体,也就是说,这个结构体将只会保存最新的调用结果。因此,localtime每次返回的struct tm结构体也将是 同一个,即指向的地址是同一个。这也就意味着,后续第23行到第25行对asctime的调用中,实际上传入的都 是同一个结构体(指向同一个地址的指针),结果它们打出来的时间一样也就不足为奇了。

我们再来 看以下这段代码:

1 #include <stdio.h>
2 #include <time.h>
3
4 int main ()
5 {
6
7 time_t time_1, time_2;
8 struct tm *tm_1, *tm_2, *tm_3;
9 struct tm tm_4, tm_5;
10
11 printf("-------------------- PART I -------------------\n");
12
13 time_1 = time(NULL);
14 sleep(3);
15 time_2 = time(NULL);
16 printf("time1:%d time2:%d\n",time_1,time_2);
17
18 tm_1 = (struct tm*)localtime(&time_1);
19 tm_2 = (struct tm*)localtime(&time_2);
20 tm_3 = (struct tm*)localtime(&time_1);
21
22 printf("tm_1 ptr:%p tm_2 ptr:%p tm_3 ptr:%p\n",tm_1,tm_2,tm_3);
23 printf("asctime(tm_1):%s",asctime(tm_1));
24 printf("asctime(tm_2):%s",asctime(tm_2));
25 printf("asctime(tm_3):%s",asctime(tm_3));
26
27
28 printf("-------------------- PART II -------------------\n");
29
30 time_1 = time(NULL);
31 sleep(3);
32 time_2 = time(NULL);
33 printf("time1:%d time2:%d\n",time_1,time_2);
34
35 tm_4 = *((struct tm*)localtime(&time_1));
36 tm_5 = *((struct tm*)localtime(&time_2));
37
38 printf("tm_4 ptr:%p tm_5 ptr:%p\n",&tm_4,&tm_5);
39 printf("tm_4 sec:%d tm_5 sec:%d\n",tm_4.tm_sec,tm_5.tm_sec);
40
41 printf("asctime(&tm_4):%sasctime(&tm_5):%s",asctime(&tm_4),asctime (&tm_5));
42 printf("asctime(&tm_4) ptr:%p asctime(&tm_5) ptr:%p\n",asctime (&tm_4),asctime(&tm_5));
43
44 printf("asctime(&tm_4):%s",asctime(&tm_4));
45 printf("asctime(&tm_5):%s",asctime(&tm_5));

时间: 2024-10-03 00:51:08

小心C语言时间函数陷阱的相关文章

【原创】C语言时间函数简介

以下内容参考自 这里 .  ======  [C 库与 C++ 库的关系] The C++ library includes the same definitions as the C language library organized in the same structure of header files, with the following differences: a. Each header file has the same name as the C language ver

c++制作的时间函数类_C 语言

实现类的定义,以及调用 Clock时间类的头文件Clock.h //#pragma once #ifndef _CLOCK_H_ #define _CLOCK_H_ class Clock { public: void Init(int hour, int minute, int second); void Display(); void Update(); int GetHour(); int GetMinute(); int GetSecond(); void SetHour(int hou

c语言计时函数返回时间不定,求详解为什么(只点击了两次运行,并未改变代码)

问题描述 c语言计时函数返回时间不定,求详解为什么(只点击了两次运行,并未改变代码) 代码如上, 结果如下: 第一次 第二次: 解决方案 同样的代码,执行过程中计算机可能遇到各种小问题,一般来说短期内第二次运行会快点. 第一次会进行资源的分配,将代码拷到内存里,再执行. 如果在很短的时间内进行第二次运行,代码还在内存里,CPU少了将代码拷到内存的操作,所以会快上一点. 你问的这个问题设计到了操作系统的CPU局部性策略,操作系统在执行程序时,并不是像C一样,顺序执行,因为同一时间,并不是只有你的程

C语言循环结构与时间函数用法实例教程_C 语言

本文实例展示了C语言循环结构与时间函数用法,对于C语言的学习来说是非常不错的参考借鉴材料.分享给大家供大家参考之用.具体如下: 完整实例代码如下: /********************************************** ** <Beginning C 4th Edition> Notes codes ** Created by Goopand ** Compiler: gcc 4.7.0 *****************************************

C语言之时间函数

在我们时间编程的时候,难免会遇到时间函数,在项目中计算现在时间以及程序中某个动作运行的时间都需要用到时间函数,在大多数入门级别的C语言以及C++语言书籍中很少提及到,大多时候需要在网上查询,今天小编在工作之余给大家整理一个时间函数例子,希望初学者能够了解简单时间函数,为以后的高层开发打好基础.请关注我呦! #include<time.h> #include<stdio.h> #include<dos.h> #include <stdlib.h> #inclu

c语言-标C的时间函数还是有点不理解,有大神么?

问题描述 标C的时间函数还是有点不理解,有大神么? 小菜鸟今天刚学了标C的时间函数,好多结论都是网上看的,不知道哪里出问题了. [结论一]time_t =0 的时候 返回的时间其实是 1970-01-01 00:00:00 到UTC 0时区的秒数,而不是 我们北京时间UTC+8:所以gmtime比localtime 小8小时. 因此time返回的时间也比本地时间少8个小时 即少 28800秒 虽然如此,但是 localtime 是将时区考虑在内了因此虽然传入的秒数UTC时间比本地时间少8个小时,

解析Linux下的时间函数:设置以及获取时间的方法_C 语言

一.时间函数 复制代码 代码如下: time_t time(time_t *t);char *asctime(const struct tm *tm);char *asctime_r(const struct tm *tm, char *buf);char *ctime(const time_t *timep);char *ctime_r(const time_t *timep, char *buf);struct tm *gmtime(const time_t *timep); //获取的为英

linux c语言 select函数用法

linux c语言 select函数用法 表头文件 #i nclude<sys/time.h> #i nclude<sys/types.h> #i nclude<unistd.h> 定义函数 int select(int n,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout); 函数说明 select()用来等待文件描述词状态的改变.参数n代表最大的文件描述词加1

R语言时间序列分析之ARIMA模型预测

R语言时间序列分析之ARIMA模型预测   今天学习ARIMA预测时间序列.  指数平滑法对于预测来说是非常有帮助的而且它对时间序列上面连续的值之间相关性没有要求.但是如果你想使用指数平滑法计算出预测区间 那么预测误差必须是不相关的 而且必须是服从零均值. 方差不变的正态分布.即使指数平滑法对时间序列连续数值之间相关性没有要求在某种情况下 我们可以通过考虑数据之间的相关性来创建更好的预测模型.自回归移动平均模型 ARIMA 包含一个确定explicit 的统计模型用于处理时间序列的不规则部分它也