小心C語言時間函數陷阱

來源:互聯網
上載者:User

在編寫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));

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.