2014-12-26 102 views
0

我是C品牌的新手,我仍然試圖瞭解它是如何工作的,任何幫助表示讚賞。 我正在通過一個代碼示例來打印出用戶屏幕上的當前本地時間。我已經評論了代碼,以幫助我瞭解正在發生的事情並對其工作原理有疑問。瞭解ctime代碼

#include <time.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main() 
     { 
     //define timeval as data type time_t 
     time_t timeval; 

     //Apply the time function, found in time.h, and use timeval as parameter 
     (void)time(&timeval); 

     //Use ctime, found in time.h, and use timeval as parameter 
     printf("The date is: %s", ctime(&timeval)); 
     exit(0); 
     } 

首先,我不是究竟是如何(void)time(&timeval)作品清晰,尤其是去除(無效)似乎並不怎麼破解程序。從閱讀中,我的理解是,當函數沒有返回時使用void,但爲什麼這很重要?不知道爲什麼它被使用。另外,timeval的數據類型在程序開始時被聲明爲time_t,但是什麼是time函數可以在ctime函數使用它時使用它。

+0

您是否閱讀過['time'](http://en.cppreference.com/w/c/chrono/time)或['ctime'](http://en.cppreference.com/) W/C /計時/的ctime)? –

+0

將ctime()的返回值轉換爲(void)並沒有什麼意思。專注於編寫明智的代碼。 –

+2

如果函數沒有返回值,則聲明爲「void」類型。 'time()'不是這樣寫的,因爲你可以接受返回值,或者使用傳遞的(更新的)參數,並且轉換(未使用的)返回值是毫無意義的。 'time()'返回自1970年1月1日午夜以來的秒數,'ctime()'將此值轉換爲可讀的時間和日期字符串。 –

回答

3

返回值的函數通常會這樣做。在這種情況下,time()返回成功時當前時間的表示形式,但如果出於某種原因無法獲取當前時間,則返回-1

您的代碼不檢查這個返回值,並且是穩健的,它應該的,因爲如果調用time()失敗,那麼你就需要有所改變的嘗試失敗的結果傳遞給ctime()你的計劃。

一些靜態分析工具,特別是lint及其現代對應,splint,將(或可以告訴)標誌,當你調用其中有你不使用返回值的函數,正是由於這個原因,一個問題 - 因爲該功能給你潛在有用的信息,你忽略了。

從語義上講,將返回值轉換爲(void)是一種在代碼中聲明顯式丟棄該值的方法。這可以說本身就有一些優點,但是代碼繁雜,但特別是它可以用來消除一些警告,因爲你告訴分析工具你故意這樣做,因此它不需要警告你。

在這種特殊情況下,time()也會將它返回的值存儲在變量中作爲其參數,因此您有兩種不同的方法來獲取它。在此輸入返回到(void)可能是一種說法:「我故意通過它的參數獲得time()的輸出結果,而且我明確地放棄了返回值,因爲我只需要一次輸出,而且我已經擁有了它。」它實際上並沒有改變代碼的功能,但是這是你在代碼中清楚你在做什麼的一種方式。如果您習慣通過它的返回值從time()獲取輸出,並且出於某種原因,在這種特定情況下,您選擇通過參數獲取輸出,但添加演員人員可能會幫助您稍後記住所做的事情,如果你的第一本能是想知道你爲什麼打電話time(),顯然不存儲結果。

無論你如何得到它,你仍然應該檢查失敗。例如,儘管你可以做這樣的事情:

time_t timeval; 
time(&timeval); 
if (timeval == -1) { 
    fprintf(stderr, "couldn't get time"); 
    return EXIT_FAILURE; 
} 
printf("The date is: %s", ctime(&timeval)); 

它很可能是更自然的事:

time_t timeval; 
if (time(&timeval) == -1) { 
    fprintf(stderr, "couldn't get time"); 
    return EXIT_FAILURE; 
} 
printf("The date is: %s", ctime(&timeval)); 

而這也正是知道你不使用的返回值可能會有所幫助,即使你通過參數得到結果。

缺點是有一些函數返回一個通常不用於檢查的值,printf()就是一個明顯的例子。如果你使用了很多這些功能,你的代碼很快就會被無用的(void)強制轉換爲混亂,而且這種技術往往會變得比注意分散注意力更多,儘管意圖很好。

+0

謝謝,保羅。這是一個了不起的解釋,我很感謝你的努力。 – Kimomaru

+0

@WeatherVane:對,'snprintf()'和'vsnprintf()'尤其如此,在這裏找出需要分配的字符串有多大,而不會觸及'n'限制。 –

2

如果不使用返回值,則不需要投射到(void)。也許有些奇怪的編譯器會在你不投射時發出投訴(例如「不使用返回值」),但我懷疑它。通常,如果您打算使用返回值,它將間接顯示爲未初始化的變量警告。

當您通過timeval引用time函數時,它將被設置爲當前系統時間。這相當於做timeval = time(NULL)

time的行爲:

該函數返回該值,以及如果參數不是空指針,它也將此值設置爲通過計時器所指向的對象。

然後傳遞給ctime將其轉換爲要打印的字符串。