素因数分解を行うプログラムにおいて、処理時間を計算する必要があります。
#include <stdio.h>
#include <time.h>

main()
unsigned long i,t0,t1;
t0 = clock();
for(i=0; i<100000; i++){

}
t1 = clock();
printf("Time : %lf\n", t1 - t0);
}

などと例を作ってテストしているのですが、小さな単位まで出てきません。
100分の1秒単位で出てきているとおもいます。
もっと細かい時間を計測するのにはどうしたらいいのでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (5件)

clock()は標準関数なので、ちょっと調べれば正しい使い方がすぐわかると思いますが・・・



まずclockの戻値はtime.h内で定義されている、clock_t型で受け取るようにしましょう。
あなたの環境ではたまたまunsigned longで実装されているのかもしれませんが、他の環境やバージョンでもそうだとは限りませんよ?

それからprintfの中ですが、unsigned long同士の引き算の結果はunsigned longになりますので、double型を期待する%lfでは正しく表示されません。
(正しく表示するには%luを使うか、(double)t1-t0としてキャストする。)

clock関数は1秒より小さい単位で時間を計測しますが、それは小数型で計測しているのではなく、秒より小さい単位を使って整数型で計測しています。(つまり単位は秒ではありません。)
これを秒単位に直すには、time.h内で定義されているCLK_TCKマクロを使います。

ではでは、下のサンプルを参考にしてみてください。

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

void main()
{
  clock_t t0, t1;
  int i;

  t0 = clock();
  for (i = 0; i < 100000; i++) {
    /* 重い処理。バブルソートなんかいいかもね */
  }
  t1 = clock();

  printf("Time:%f\n", (t1-t0) / CLK_TCK);
  /* そういやdoubleは%fでした。long doubleは%Lfだし…。%lfって何!? */
}
    • good
    • 0
この回答へのお礼

ありがとうございました。
無事解決することができました。

お礼日時:2001/04/27 13:01

unixであればgettimeofdayで秒とマイクロ秒が取得できます。



struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};

です。
加工すれば、目的となる数値が計算できるでしょう。
forのループは中で何か計算しないと最適化されて無くなるおそればあります。
また、unsigned longの値をdouble型で出力するのもどうかと思われます。


#include <sys/time.h>
#include <unistd.h>

main(){
struct timeval tm;
struct timezone tz;

gettimeofday(&tm, &tz);
}

windows系だと解りません。
    • good
    • 0
この回答へのお礼

ありがとうございました。
無事解決いたしました…。

お礼日時:2001/04/27 13:00

こんにちわ。



これは、プログラミングをしている環境(OS)によって違ってくるのではないでしょうか?
例えば、FreeBSD(UNIX系?)ではgetrusageというシステムコールがあり、これを利用することで計測することができます。
あとは、複数回の計測を行い、上下のデータを外した平均を取るという方法もあったはずです。少なくとも1回の計測では、キャッシュの影響などが大きく出すぎるのではないかと思います。
    • good
    • 0
この回答へのお礼

ありがとうございました。
無事解決することができました…

お礼日時:2001/04/27 12:59

WindowsのAPIでQueryPerformanceFrequencyとQueryPerformanceCounterを使えば、CPUにもよりますが、高分解能で出てきます。



また、Windowsでない場合、同一処理を数千回~数万回の単位繰り返し処理させ、その時に掛かった処理時間/実行回数の平均を取ると大体の1回辺りの処理速度が計算できます。
    • good
    • 0
この回答へのお礼

ありがとうございました。
無事解決いたしました…。

お礼日時:2001/04/27 12:59

質問での例だと最適化されてfor分自体が無くなってしまう可能性がありますね。


もう少し何かをやらせるようにしないと例として成り立ちません。
    • good
    • 0
この回答へのお礼

ありがとうございました。
無事解決いたしました…。

お礼日時:2001/04/27 12:58

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC言語のソースコードの書き方

C言語のソースコードの書き方に関する質問です。
0を5個と1を4個の、合わせて9個の数字を並べて出来上がる数列のパターン(126通り)を全て羅列させるプログラムを作りたいと考えていますが、そのためにどういった方針を立ててソースコードを書けばよいかが分かりません。
どういった構造かだけでも構いませんので、教えて頂けると幸いです。
よろしくお願いします。

Aベストアンサー

という方針で書くとこんな感じね。
#include <stdio.h>

void
print_pattern(char pattern[], int size)
{
for (int i = 0; i < size; i++) {
printf("%c", pattern[i]);
}
printf("\n");
}

void
iter(char pattern[], int end, int n, int m)
{
if (n == 0 && m == 0) {
print_pattern(pattern, end);
return;
}

if (n == 0) {
pattern[end] = 'b';
iter(pattern, end + 1, n, m - 1);
return;
}
if (m == 0) {
pattern[end] = 'a';
iter(pattern, end + 1, n - 1, m);
return;
}

pattern[end] = 'b';
iter(pattern, end + 1, n, m - 1);
pattern[end] = 'a';
iter(pattern, end + 1, n - 1, m);
}

int
main(void)
{
int m = 5, n = 4;
char pattern[m + n];
iter(pattern, 0, m, n);
return 0;
}

という方針で書くとこんな感じね。
#include <stdio.h>

void
print_pattern(char pattern[], int size)
{
for (int i = 0; i < size; i++) {
printf("%c", pattern[i]);
}
printf("\n");
}

void
iter(char pattern[], int end, int n, int m)
{
if (n == 0 && m == 0) {
print_pattern(pattern, end);
return;
}

if (n == 0) {
pattern[end] = 'b';
iter(pattern, end + 1,...続きを読む

Qfor(int i = 100, long n = 1; i > n/3i; i++)

for(int i = 100, long n = 1; i > n/3i; i++)
のように、初期設定で型の違う変数を宣言したいんだけど
C++ではこんなふうに2つ以上の型を宣言してはいけないんですか?

Aベストアンサー

,

コンマ演算子の原理です。
forの初期化文で "," で区切れるのは値を返す文だけです。
よってintステートメントもlongステートメントも値を返さないので、この文では使用できません。

というか、むしろ、intステートメントの第2引数としてlongが認識されてしまいます。
外で

int i; long n;

とし

for(i = 0, n = 0; hoge; hoge)

なら可能です。

QC言語のソースコードについて教えてください。

以下のソースコードを学習用C言語開発環境で行ったのですが、
『ファイル「C:/Users/ユーザー名/AppData/Local/EasyIDEC/project/タイトル/main.c」の
「41行目」で記述エラーを発見しました。
「,」を付け忘れています。』

という、コンパイルエラーが表示されました。
何度も見直したのですが、よくわかりません。

#include <stdio.h>

int main(int argc, char *argv[])
{
char answer ;
answer = 'n' ;

while(answer =='n')
{
int input ;
input = 0 ;
int add ;
add = 1 ;
int sum ;
sum = 0 ;

printf("数値を入力して下さい。:") ;
scanf("%d", &input ) ;

int i ;
i = 0 ;

while(i < input)
{
sum =sum + add ;
printf("\n%d",sum) ;
i++ ;
add++ ;
}

printf("\n1から%dまでの総和は、%dです。" , input , sum) ;

while(1)
{

printf("\n終了しますか? y/n:") ;
scanf(" %c , &answer) ;

if( (answer != 'y') && (answer != 'n') )
{
printf( "y or nを入れてください。") ;
}
else
{
break ;
}
}
}
return 0 ;
}

以下のソースコードを学習用C言語開発環境で行ったのですが、
『ファイル「C:/Users/ユーザー名/AppData/Local/EasyIDEC/project/タイトル/main.c」の
「41行目」で記述エラーを発見しました。
「,」を付け忘れています。』

という、コンパイルエラーが表示されました。
何度も見直したのですが、よくわかりません。

#include <stdio.h>

int main(int argc, char *argv[])
{
char answer ;
answer = 'n' ;

while(answer =='n')
{
int input ;
input = 0 ;
int add ;
add = 1 ;
int sum ;
sum = 0 ;

printf("...続きを読む

Aベストアンサー

>>おかげで、エラー表記されずに、プログラムが実行されました。

これはコンパイルがうまく完了したってことでしょうか?できあがったプログラムが実行できたってことではないですよね?そうなら

>>’タイトル’は内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。」

なんて問題は起きないはすですからね。

できあがったファイルは、XXXX.EXEのように拡張子のEXEがついていますか?もしXXXX.OBJであれば、リンクができていませんから、実行できません。

学習用C言語開発環境の使い方を確認してみてください。

P.S.
昔は、コンパイラを使うのは大変でしたが、今は楽ですね。CではなくPascal系コンパイラーですが、カセットテープに入っていて、コンパイラの読込にテープレコーダで15分かかったりとか、まあ大変だけど面白い時代でした。

Qfor( ; ti >= 0; ti--, ci++)

C言語のループの表記のことです

for ( ; ti >= 0; ti- -, ci++)
この意味がわかりません
自分なりに解釈すると「;ti >= 0」から始まって「 ci++ 」を繰り返しながら「 ti- - 」になるまで繰り返す、というような感じです

「;ti >= 0」から始まるとはどういう意味でしょうか?
「 ti- - 」になるまでとは???

このソースが書かれているHPです
http://www.rs.kagu.tus.ac.jp/infoserv/j-siken/H12a2/pm11.html
52行目になります


わかる方がいらっしゃったら教えてください、お願いします

Aベストアンサー

for() の 「初期設定式」「継続条件式」「再設定式」の区切りは、; です。
ですからこの場合、
初期設定式:なにもない(特に初期設定不要)
継続条件式: ti >= 0
再設定式: ti--, ci++
です。

さらに、再設定式に出てくる表現は、「コンマ演算子」といいまして、おおざっぱに言えば、コンマで区切られた式を順番に実行という意味です。
(関数の引数に現れるコンマとは別の意味です)

初期設定式のない for() は、すでにあるところから処理を継続する場合によく使われます。たとえば、

s = 0;
for (i = 0; x[i] == 0; i++); // x[i] の先頭部分の0の要素を捨てて
for(; x[i] > 0; i++)
s += x[i]; // 「そのあと」の正の部分が継続する間足し込む
という場合、

また、再設定式は、

for(i = 0, j = 10; src[i] != 0; i++, j--)
dest[j] = src[i];
のように、二つ(以上)のものを変化させたい場合。
この例では、初期設定式も、コンマ演算子を使って、2つの初期化を行っています。

for() の 「初期設定式」「継続条件式」「再設定式」の区切りは、; です。
ですからこの場合、
初期設定式:なにもない(特に初期設定不要)
継続条件式: ti >= 0
再設定式: ti--, ci++
です。

さらに、再設定式に出てくる表現は、「コンマ演算子」といいまして、おおざっぱに言えば、コンマで区切られた式を順番に実行という意味です。
(関数の引数に現れるコンマとは別の意味です)

初期設定式のない for() は、すでにあるところから処理を継続する場合によく使われます。たとえば、

s = 0;
...続きを読む

QC言語ソースコードに関する質問です。

以下の数列について,初項から第15項までを求めるプログラムと実行結果を示せ。
0 1 1 2 3 5 8 13 21(ただし,初項=0,第1項=1とする。)

ソースコードを書くと、エラーがでた。
#include <stdio.h>
int fib(int n)
{
if(n==1 || n==2)
return 1;
else
return fib(n-1)+fib(n-2);
}
int main(void)
{
int n;
for(n=0;n<17;n++)
printf("%d,",fib(n));
}

正しソースコードを教えてください!

よろしくお願いします。

Aベストアンサー

#include <stdio.h>

void fib(int i, int j, int n)
{
if (n == 1)
{
printf("%d\n", i);
}
else
{
printf("%d\n", i);
return fib(j, i + j, n - 1);
}
}

int main(void)
{
fib(0, 1, 15);

return 0;
}

Qtemplate A(const T &t=T())

template<class T> A(const T &t=T());
という関数宣言において引数のところの解釈に戸惑ってます
どういう風に解釈したらいいのか教えていただければ幸いです

Aベストアンサー

引数 t は型Tのconstな参照体であり、
T()をデフォルトとする。
# 戻り値がありませんよー

class Foo {
public:
Foo();
Foo(int);
...
}

Foo f(5);
A(f);
A(); // = A(Foo()) と同じ

Qc言語のソースコードを教えて下さい

キーボードから10個の正整数値を読み込み,合計値を表示するプログラムを作りなさい。
ただし,キーボードから読み込んだ値はint型変数xにしまわれるものとし,変数はこのxと回数を数えるint型変数countと合計値をしまうint型変数sumのみを用いることとする。

このプログラムのソースコードを教えて下さい。
解説もよろしくお願いします。

Aベストアンサー

一例です。
添付のURLを参照して下さい。
因みに、平均値も算出しているが気にせずに、後はご自身で変数、コードを要調整して下さい。

参考URL:http://www.geocities.jp/kenji_y0328/crenshu/renshu/r021.gif

Qint i,j; \n i=0,j=5;

int i,j;
i=0;
j=5:
と書いてあるソースは普通ですが、
int i,j;
i=0,j=5:
と書いてあるソースもあります。
後者はC++の正しい書式ですか?

カンマ演算子というのは後者のカンマのことですか?

Aベストアンサー

 正しい書式です。

i=0,j=5;
 における、「,」をカンマ演算子といいます。2項の演算子です。カンマで区切られた演算を「左から順番に」実行し、最後の演算を結果として返します。
 したがって、例の文であれば、i=0を実行し、次にj=5を実行。そして、j=5の結果の5を結果として返します。
 ・・・
 が、本来的には、あまり、例のような使い方はしませんね。よく見られるのは、次のような場合です。

 for (i=0,j=0 ; i < 50 ; ++i,++j) {

 のような形でよく見られます。for文の各式は、一つの式でなければならないので、こんな書き方をするわけです。初期化と更新部が一つにまとまり、ループが読みやすくなるのが利点かな。

Qソースコードの間違い (C言語)

変数に、文字列を入れた配列の文字列の最後の要素数を入れたいのですが(つまり'\0')、うまくいきません。いつも2個多い値になってしまいます。

#include <stdio.h>

void main() {
char moji[100]={0};
int c=0;

fgets(moji,sizeof moji,stdin);

while( moji[c] != '\0' ) ++c;

printf("\n%d\n",c); //
}

例えば5文字の1ビット文字を入れると、最後の文字はmoji[4]にあるのでprintfで4と表示されるはずじゃないですか。でも6になるんです。いつも+2の値になるんですよ。どうやらfgetsを使っているからそうなるらしく、scanfを使うと結果は1多い値に、普通に配列に直接文字列を代入すると正常な結果になります。別にcに-2してもいいのですが、それはなんだか癪といいますか・・・。なぜこういうことがおきるのでしょうか?回答よろしくお願いします。

Aベストアンサー

>なぜこういうことがおきるのでしょうか
そのmoji[]の余計な部分にはどんなコードが入っているかは確認していますか?
リターンキーも「キー入力」の一つですよ。

Q#include

#include <stdio.h>の <> の意味と
#include "xxxxx.h"の "" の意味を教えてください。

Aベストアンサー

厳密な定義を、「JIS X3010:2003 - 6.10.2 ソースファイル取り込み」から引用します。

---- 引用ここから ----
制約 #include指令は, 処理系で処理可能なヘッダ又はソースファイルを識別しなければならない。
意味規則 次の形式の前処理指令
    # include <h文字列> 改行
は, 処理系定義の場所を順に探索して, <区切り記号と>区切り記号の間で指定した文字列で一意に決まるヘッダを見つけ, そのヘッダの内容全体でこの指令を置き換える。どのようにして探索の場所を指定するか, またどのようにしてヘッダを識別するかは, 処理系定義とする。
 次の形式
    # include "q文字列" 改行
は, 二つの"区切り文字の間で指定した文字列で一意に決まるソースファイルの内容全体で, この指令を置き換える。指定したソースファイルの探索順序は処理系定義とする。この探索をサポートしていない場合, 又は探索が失敗した場合, 同じ文字列(もしあれば>文字を含めて)を含む次の知れに読み替えたのと同じ規則で再処理する。
    # include <h文字列> 改行
---- 引用ここまで ----

要するに、<xxx>の場合は処理系定義のヘッダ(ファイルとは限らない)を取り込み、"xxx"の場合はソースファイルを取り込むということです。いずれも探索場所やその順序は処理系定義です。

よくある誤解は、
・ヘッダは必ずファイルである。
・"xxx"ではカレントディレクトリや取り込もうとしたファイルと同じディレクトリから探索を始める。
といったものです。このように実装されている処理系が多いことは確かですが、標準規格ではそのような規定はありません。
使用している処理系がどのような実装になっているかは、マニュアルに記載があるかと思います。

厳密な定義を、「JIS X3010:2003 - 6.10.2 ソースファイル取り込み」から引用します。

---- 引用ここから ----
制約 #include指令は, 処理系で処理可能なヘッダ又はソースファイルを識別しなければならない。
意味規則 次の形式の前処理指令
    # include <h文字列> 改行
は, 処理系定義の場所を順に探索して, <区切り記号と>区切り記号の間で指定した文字列で一意に決まるヘッダを見つけ, そのヘッダの内容全体でこの指令を置き換える。どのようにして探索の場所を指定するか, またどのようにして...続きを読む


人気Q&Aランキング