• 締切済み

初級者の質問――time_tについて

私はC言語の初級者です。 time関数というのは現在時刻をtime_t型で返すものですよね。 でも、私はこの意味がよくわかりません。 time_t型とは何でしょうか。 単なる整数なのでしょうか。 確か、time_t型というのは整数で、 1970年1月1日0時からの秒数(世界標準時)だと聞いた気がします。 しかし、(いくつか見てみましたが)大抵のC言語の本では、そういう説明はしていません。 「プログラミング言語C」(カーニハン、リッチー)という本では、 「timeは現在のカレンダー時間を返す。」 と説明しています。 「じゃあ、カレンダー時間って何?」と思いますが、「カレンダー時間」というものの説明は見当たりません。 time_tというのは整数と考えてよいのでしょうか。 time_tで変数宣言すると、プログラムを読む人が「あ、これは時間を表すんだな」とわかり易いから、time_tというものがあるのでしょうか。 それとも、 time_tが秒数を表すかどうかは処理系に依存するのでしょうか。 もし、1970年1月1日からの秒数を表すなら、time関数の戻り値を1年間の秒数で割って1970に足せば今何年かわかるプログラムになりそうですよね。(うるう年や時差は考慮する) それとも、それは処理系によっては正しく動かないプログラムになるのでしょうか。 (あくまでも考え方です。確か、time_tを渡せば年月日時分秒を返す関数があると思います。) ちなみに、おとといプログラムを作ってtime関数の戻り値を10進数で表示すると次のようになりました。(VC++) ==============プログラム============== #include <stdio.h> #include <time.h> int main(void) { time_t a; a=time(NULL); printf("%d\n",a); return(0); } ================結果=============== 1005300371

noname#1254
noname#1254

みんなの回答

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.7

> C99とは、ISOの規格で比較的新しいものと思います。 そうです。 正式にはISO/IEC 9899:1999です。 > (C98というのは知りませんでした。) 失礼しました。 C89の間違いです。 同様にISO/IEC 9899:1989です。 > しかし、時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、かまわないのでしょうか 時間の起点(というか、時間の管理方法)は time()の管轄であり、型であるtime_tは「time()が返す値を表現できること」が要求されているに過ぎません。 また、「1970年1月1日0時0分0秒からの経過秒数」というのは慣例に過ぎません。 とはいえ、UNIXを起源とする『time_tはlong』と『time()は1970年1月1日0時0分0秒からの経過秒数』という約束事は変えられる事は無いでしょう。 C98/C89との互換性を保ちながら新規格を作ることが予想されるからです(そうでなければlong longなどという型は作らないはず)。 その意味でyoushirさんのおっしゃるとおりだと思います。

noname#1254
質問者

お礼

>時間の起点(というか、時間の管理方法)は time()の管轄であり、型であるtime_tは「time()が返す値を表現できること」が要求されているに過ぎません。 ということは、C言語の本で time関数はいついつからの秒数を返します、 などと書かない理由は自明ですね。 (No.6の回答より) >ANSI-Cにおいて「time_tは整数値」という規定があります。 time_tが整数値でなくてはいけないのか(time_tがdoubleでも規格に反しないのか)という点まで突っ込んで考えればきりはないですが、 私のような初級者がそこまで知る必要もないでしょう。 (質問から) >それとも、それは処理系によっては正しく動かないプログラムになるのでしょうか。 そういう可能性があるということですね。

noname#1254
質問者

補足

(締め切る前に―――ここの回答とは直接の関係はないですが) time関数は、失敗したとき(無効の場合)、 (time_t)-1、つまり、time_tでキャストした-1 を返します。 (質問は規格に関するものですが、規格のことは置いておいて。) 戻り値が負の数である可能性があることを考えると、time関数の戻り値の型は、 符号付きの型になっているのが自然のように思われます。 (キャストすれば何でもいいだろう、という考えは、確かにそれはそうですが。)

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.6

ANSI-Cにおいて「time_tは整数値」という規定があります。 よってC98ではshortまたはlong、C99ではshort/longまたはlong longのいずれかとなります。

noname#1254
質問者

補足

ご回答ありがとうございます。 わたしの知識が正しいか、自信がないですが… C99とは、ISOの規格で比較的新しいものと思います。 (C98というのは知りませんでした。) 今、私の手元に『新ANSI C言語辞典』(技術評論社)という本があるのですが、それによると、 ・time_tは算術型である。 ・算術型とは、汎整数型と浮動小数点型の総称。 ということがわかりました。 ご回答に照らしても、 「time_tが構造体であっても、 問題ないわけですね」(#4補足)なる私の発言は暴論であることがわかります。(ANSI C の場合。) しかし、時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、かまわないのでしょうか(ANSI C の場合)。(もしかして、これも暴論かもしれません。) こういうことは言えませんか? time_t型が1970年1月1日0時からの秒数だと規格で決まっているならば、time関数の戻り値の説明をするときに、 戻り値はカレンダー時間(暦時間)である、 などと奥歯にものの挟まったような言い方をしないで、素直に「1970年1月1日0時からの秒数」だと言えばよいと思いませんか?

  • ykkw_2001
  • ベストアンサー率26% (267/1014)
回答No.5

こんにちは、 >時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、time_tが構造体であっても、 >C言語としては問題ないわけですね ? 時間関係は、混乱しやすいですよね。 多分その目的には、tm 構造体というのが適しているように思います。 また、独自の時刻データ型を作る場合は、MyTime_t などのように、他の人にもわかる名前にする事をお勧めします。 確かに自分だけが見る趣味のプログラムなら、「time_tが構造体であっても、C言語としては問題ない」ですけど、他の人が見る仕事関係のプログラムでは、標準(言い換えると常識的)ではない定義があると、他の人はすんごく迷惑します。 少なくとも私の回りでは、そのようなことは「禁止」にしています。「エラーが出ないからOK」とか「このほうが(自分で)わかりやすい」からと好き放題したプログラムのトラブルを直す実力になり、同様の事を経験したら、このことは、実感としてご理解いただけると思います。 (このような「前提が変」という問題だけは、よく泣かされます) 初心者の方ということなので、今後を思いあえて書かせていただきました。

noname#1254
質問者

お礼

ありがとうございます。

  • brogie
  • ベストアンサー率33% (131/392)
回答No.4

小生はC++Buiderですが、 time.h を見ますと次のように定義してありました。 typedef long time_t; 以上です.

noname#1254
質問者

補足

ありがとうございます。 私の本来の質問は 「C言語と呼ぶにあたって、time_tが整数である必要はあるのか」 という点に質問の重点があったわけですが、 #1の補足で述べましたように、私は 「実際にそのような(整数でない)処理系はあるのでしょうか。 」 ということもあわせて聞いています。 後者に関することとしてお答えいただいたわけですね。C++Buiderもlongだということですね。 参考になります。 皆さんにご確認を取りたいと思います。 time_tが1970年1月1日からの秒数だということはC言語として必須ではなくて、 時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、time_tが構造体であっても、 C言語としては問題ないわけですね ?

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.3

>time_t型とは何でしょうか。 現在時刻を返すための型です。 intとしないのは、今後、例えば128bit整数が必要になった場合でも, インクルードファイルやライブラリを変えて、コンパイルしなおすだけで対応できるようにするためです。 当然,intでなくても構いませんし,2038年までには変わるだろうとは思います。 32bit整数だと2038年に桁数がたりなくなるからです。 既にそうなっているOSもあるだろうと思います。 もし、intとしてコーディングすると、こういう変更がおきた場合に、ソースコードレベルで修正が必要です。 それも、どこにどの程度あるのか簡単にわかりませんから、手間もかなりかかります。 また、他の環境では現在でも違う可能性がありますから、同じソースを違う環境で動作させるためにも time_t型にしておく必要はあります。

参考URL:
http://member.nifty.ne.jp/shyu/20xx/2038.htm
noname#1254
質問者

お礼

とてもよくわかりました。 「time_tって書いてあると時刻ということがわかり易いから、time_tというのがある」というよりも(そういう側面もありますが。)、 long型では、いちいちソースを見て直さなければいけないため、2038年問題に対処するのが困難だ、ということですね。 2の31乗 = 2,147,483,647秒 = 68年とちょっと・・ (参考URLより。) >他の環境では現在でも違う可能性がありますから、同じソースを違う環境で動作させるためにも >time_t型にしておく必要はあります。 よくわかりました。

noname#9414
noname#9414
回答No.2

補足読みました。 time_tがlong/intでない処理系ということですが、たいていのC言語の環境はANSI C+拡張であることから考えても、まず問題はないと思います。 #手元にANSI Cの環境がないので、何ともいえませんが。 もう少しほかの方の環境も聞いてみてもいいかもしれませんね。 ではでは☆

noname#9414
noname#9414
回答No.1

一応Visual C++ではtime.hの中にtime_tはlongという風に宣言してありますね。 従って、中身は単純なlong型。一応これは対外の環境で問題は出ないと思いますよ。ただ、MSDNにはlong intと書かれているので、int型(longと同等の)と扱われる場合もあるようです。long宣言しておけば問題はないと思います。 まぁ、time_tを使う理由はやはり「みてすぐにわかるから」だと思いますよ。 ではでは☆

noname#1254
質問者

補足

ありがとうございます。 >Visual C++ではtime.hの中にtime_tはlongという風に宣言してありますね。 >time_tを使う理由はやはり「みてすぐにわかるから」だと思いますよ。 Visual C++の場合はわかりました。 そうすると、問題は、Visual C++に限らない「C言語一般」の場合はどうなのか、ということになりますね。 time_tがlongでもintでもない処理系があっても、C言語の規格として問題はないのでしょうか。 また、実際にそのような処理系はあるのでしょうか。 (なお、今私の扱っているコンピュータには、Cどころかプログラミング環境がないので、VC++のこともわかりません。今は。)

関連するQ&A

  • C言語の質問です。

    C言語の質問です。 C言語で、PCの時間を、キーボードで入力した好きな秒数ごとに表示するプログラムを作りたいのですが、どうしても1秒ごとになってしまいます。ここまで作ったのですが、あとどのようにすればよろしいでしょうか? #include <stdio.h> #include <time.h> #include <string.h> int a2i(char x); main() { time_t jikoku; char t[30]; int h,m,s,so=0; int x,a; printf("秒数xを入力"); scanf("%d",&x); while(1){ for(a=0;a<x;a++){ time(&jikoku); strcpy(t,ctime(&jikoku)); h=a2i(t[11])*10+a2i(t[12]); m=a2i(t[14])*10+a2i(t[15]); s=a2i(t[17])*10+a2i(t[18]); if(s!=so+a){ printf("%d:%d:%d\n",h,m,s); so=s; } } } } int a2i(char x) { return(x-'0'); }

  • time()関数について

    このたび、一定処理にかかる時間を調べるために、 次のようなプログラムを作成しました。 #include <stdio.h> #include <time.h> int main(void) { int i; long time; time_t t1, t2; time(&t1); for (i = 1; i <= 5000; i++) { printf("%d, ", i); } time(&t2); printf("\nTime1 = %lf\tTime2 = %lf\n", t1, t2); time = t2 - t1; printf("かかった時間:%lf\n", time); return 0; } 1-5000まで、数字を表示するために、 こういうプログラムを作ったのですが、 どうもtime()関数のところでエラーが出ます。 関数でないものを呼び出している(関数 main ) とでます。time.hをインクルードしてあるのですが、 何が原因なのか分かりません。 コンパイラはBCC5.5を使っています。 ご教授願います。

  • time関数

    time関数で取得した値をファイル名として、任意のディレクトリにファイルを作成したいのですが、実装方法がわかりません お分かりの方、教えていただけませんでしょうか #include<stdio.h> #include <stdlib.h> #include <time.h> #include<sys/types.h> #include<unistd.h> time_t time(time_t *tloc); int main(void){ char keys[16] = "\x00"; time_t t; t = time(&t); printf("%ld\n", t); FILE *fp; fp = fopen(・・・・・ "w");    :     :     : fclose(fp);

  • c言語 最大公約数

    C言語のプログラムについてです。 2つの正の整数x,y(任意)の最大公約数、最小公倍数を求めるプログラムを作ってください。(それぞれ、1個ずつ) ただし、関数は使わないでください。#include<stdio.h>のみ 回答よろしくお願いいたします。

  • C言語プログラム能力検定の問題でわからないところがあります

    今度C言語プログラム能力検定を受けるのですが、過去問の回答ではわからず質問させてもらってます(以下ソース) ------------------------------------------ #include<stdio.h> int mod(int a, int b); int d, f = 10; main() { int a,b,c; enum cl {g,h} a=12; b=5; c=mod(a,b); a++; ++b; c=mod(a,b); printf("c=%d\n",c); ←(1) } int mod(int b, int a) { int c; c=b/a; c=b-c*a; return(c); } -------------------------------------------------- 問題は(1)はどのように出力されるでしょう?といったもので、 答え(出力結果)は「1」でした。回答の説明によると 「変数cはmain関数内で宣言され、mod関数の戻り値が格納される。 mod関数の戻り値は二つの引数の剰余であり、ここでは2回目のmod関数 の戻り値が表示される。2回目の仮引数は、aが6で、bが13で戻り値は1になる」 ということでしたが>mod関数の戻り値は二つの引数の剰余であり… というのがよくわかりません…剰余算というのは「%」のことですよね? であれば「c= a % b」といった記述がでてくれば13÷6=2…1で「1」となり、理解できるのですが、それらしき記述がないので(--;) どなたか教えていただけないでしょうか? よろしくおねがいします。

  • 【C言語プログラミング】 time()関数について

    現在の時刻を表示させるプログラムをC言語で作成したいのですが、 書籍などを参考に以下のコーディングを行いました。 #include <stdio.h> #include <time.h> int main(void) { time_t timer; /* 現在の時刻を取得する */ timer = time(&timer); /* 現在の時刻を出力する */ printf("現在の時刻: "); printf("%s", ctime(&timer)); printf("です。\n"); return 0; } 質問内容は以下の通りです。 (1)「time_t timer;」とは、time_t型の変数timerを宣言し、   この変数にはtime()関数で取得した現在時刻の値が入る? (2)「timer = time(&timer);」に関して、time()関数で取得した値   を変数timerが指すアドレスの場所に入れる? その場合、   返り値を格納する変数timerに、time()関数の引数と同じtimerが   指定されているのはなぜ? (3)プログラムを実行すると以下の結果となる。(time.exeを実行)   C:\>time   現在の時刻: 12:52:07.61   新しい時刻を入力してください:   現在の時刻を表示した直後に「新しい時刻を入力して下さい」が   表示される。これはtime()関数の仕様どおり? 以上です。初歩的な質問で申し訳ございませんが、ご回答よろしく お願いいたします。

  • 関数内の変数の扱い方に関する質問です

    Aという関数を作って、メイン関数内の時刻t(0から100)において10おきにplanという変数を変えるプログラムをつくっています。 しかし、メイン関数内の、if(plan == 2){printf("実行\n");}の部分が無視されてしまいます。(関数A内で使ったplanという変数はメイン関数では使えないのですか??)planが2の時に実行と表示させたいのですが、良い方法はありませんでしょうか?どうかよろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<math.h> #include<string.h> int A(int ,int); int main() { int t=0,plan; for(t=0;t<100;t++){ A(t,plan); if(plan == 2){printf("実行\n");} } return 0; } int A(int t,int plan) { if(t % 20 < 10) plan = 1; else plan = 2; }

  • srand(time(NULL))の使い方

    C言語の勉強中で「ランダムな整数値を作成し、その数値が偶数か奇数かを判定するプログラムをif~else 構文を使って作成」したいのですが下記のプログラムでやってみたのですがまだまだ知識不足で完成しません。知識をお借りできればと思っていますのでどなたか教えてください。 #include<stdio.h> #include<stdlib.h> #include<time.h> int main(void) { { int = i; i = rand(); srand((unsigned)time(NULL)); printf("%d\n",rand()); } if(i % 2 == 0) { printf("偶数である:\n",i); } else { printf("奇数である:\n",i); } return 0; }

  • difftime()について

    difftime()は、秒数の差を返すものなのに、なんでdouble型を返す仕様になっているのでしょうか? double difftime(time_t time1, time_t time0); 関数 difftime() は時刻 time0 から時刻 time1 までの経過時間を double 型で返す。 2 つの時刻の値はカレンダー時間で指定する。カレンダー時間とは紀元 (協定世界時 (UTC) 1970年1月1日 00:00:00) からの経過秒数である。 http://www.linux.or.jp/JM/html/LDP_man-pages/man3/difftime.3.html

  • 何番目に作成されたのかを表示させる方法

    ある範囲内で整数を複数個、適当につくり、その整数の平均値を取った後、適当に作った整数と最も近い平均値が何番目に作成されたのかを表示させるという問題についての質問です。 とりあえず1から100までの整数、その数10個にして、 #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int a[9]; int ave; time_t t; int i; int sum; srand(time(&t)); for(i = 0; i < 10; i++){ a[i] = rand() % 100; printf("ransu%d\n", a[i]); } ave += a[i] / 10; printf("ave%d\n", ave); return 0; } と、すればとりあえず乱数10個は生成されたのですが、何故かaveの値が合いません。 あと、この生成された乱数とaveの絶対値の差が最も小さいもの=最も平均値と生成された乱数の値が近い、と言うプログラムを書けば良いのだと思うのですが、その場合、どの様な式を使えば導き出せるのか、教えて頂ければ幸いです。 よろしくお願いいたします。