• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C++勉強中(課題にとりかかる前に))

C++勉強中(課題にとりかかる前に)

このQ&Aのポイント
  • C++勉強中のpatatasさんが、課題に取りかかる前に質問です。
  • 質問は、コード内のswitch文の役割についてです。
  • また、プリプロセッサ変数DYNが定義されている場合と定義されていない場合の実行時間比較や、コンパイラオプティマイゼーションを用いた実行時間調整など、さまざまな課題に関する情報をまとめています。

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

課題2だけ回答します。 >私の問題は、この switch 文の動作は分かるけれど、何のために あるのかが分からないという事です。 コマンドラインから実行回数が指定された場合のみ、 times の値をその指定された回数にするためです。 指定しない場合は、 case 2:    times = atoi( argv[1] ); が実行されないので、 times = 100000000が採用されます。 で、ここからが、実際の課題ですが、 コマンドラインで適当な実行回数(例えば100000000)を入力し、 時間を計測します。それが、0.3秒かかるなら、 実行回数を1/3にします。それで、実行時が、約1/3になります。 これが、0.1秒を見つける方法です。 そのようにして、0.1秒から100秒になる実行回数を見つけます。 但し、入力できる数値の上限は約2100000000です。(int型の上限)

patatas
質問者

お礼

ご回答ありがとうございます。恥ずかしながらコマンドラインから 実行回数が指定できることを知りませんでした。なんらかのフラッグを 付けることを期待されていると思い、switch 文が実行されるためには 数字を含むようなフラッグを探さなければならないと思って詰まって おりました。 これからもよろしくお願いいたします。

すると、全ての回答が全文表示されます。

その他の回答 (7)

noname#88772
noname#88772
回答No.8

こんにちは。 まだ基礎ができてないうちは回答者さんの内容が正確に理解できないと思います。 まず基礎を固めることから始めてください。 その為に資源を有効に活用してください(テキスト、クラスの講師)。 会社がやれと言ってるので遠慮なんかいりません。 頑張って下さい。

patatas
質問者

お礼

アドバイスありがとうございます。 まさに、基礎がなく、知らない事ばかりでせっかくのクラスも ここの皆様の回答も消化不良気味で焦っています。まわりの リソース(上司やクラスの講師)にも「そんなことも知らないのか」と 言われるのを恐れて活用しきれていません。そこで匿名でこの場で 質問させていただいたのですが、皆さんが親切に答えて下さって 本当に感謝しております。もちろん、一通りの知識を身につけて、 より的確な質問ができれば良いのですが、「何がわかっていないかも 分からない」状態の私の質問にできるかぎりの答えをして下さって、 勉強のスピードも効率も非常に向上(当社比)しました。 もっとまともな質問ができるようにしたいですが、ご回答者の方も 含め、みなさまこれからもよろしくお願いいたします。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

「基礎知識が欠けている」と思うなら, 多分しかるべき本を読んだ方がいいと思います. 「C++ を習得するように」と言った人に, 「初心者にもわかりやすい本をいくつか挙げてください」と言ってみるといいかも.

patatas
質問者

お礼

アドバイスありがとうございます。仰るように、基礎知識は本から 自習するのが一番だと思います。分かりやすそうな本を買って 読み始めていますが、一通りの知識を得るのもまだまだ大変そうです。 クラスに入れてくれた上司にも、おすすめ本を聞いてみようかと 思います。

すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.6

課題1 プロプロセッサ変数なるものは存在しません。 環境不明なので、timeコマンドとかuser timeとかいわれても困ります。 課題2 これも環境次第ですが、通常、このようなソフトタイマ(的なもの)で正確に実行時間を調整することはできません。 課題3 処理系不明のため、何ともいえません。 課題4 まずは結果次第ですね。 ひとついえることは、new演算子を用いているほうは例外が送出される可能性があるということです。結果として、プログラムの振る舞いが変わります。 課題5 そういう慣例だから。 Cの場合、NULLマクロは、通常、0、0L、または((void*)0)のどれかに定義されますが、C++では、通常、0または0Lに定義されるので、NULLを使っても問題ありません。 課題6 deleteのオペランドが空ポインタであれば、何もしないことが規格上保証されています。ちなみに、free関数に空ポインタを渡しても何もしないことが保証されています。 ちなみに、 extern "C" int atoi( const char *str ); はダメです(少なくとも移植性がありません)。 C++では、標準CライブラリがC結合であるかどうかは処理系定義です。C++結合の場合にこのような記述をすることはできません。

patatas
質問者

お礼

詳しいご回答、ありがとうございます。 課題1 「プリプロセッサ変数」と書いてあるのは #define DYN の DYN のことだと思います。 仰る通り、time コマンドの結果はシェル等の環境に依りますね。 オーダーとしてどうかという意味だと思います。 課題2、3 これもオーダーとしてだと思いますが、短い時間(例えば 0.0001 秒) 等は不正確でしょうね。 課題4 はい。実は課題2、3でうまく答えが出ずに苦労しております。 課題5 NULL についてですが、NULL は C での cstdlib header で定義された プリプロセッサ変数なので、C++ では cstdlib header を include しなければ未定義ということでいいでしょうか。 課題6 慣例なのですね。 すべてに丁寧に説明して下さってありがとうございました。 しかし、本ご回答者を含めた多くの方からヒントを頂いても、 やはり私は分かってないことが分かりました。 switch 文の終わりまでは理解できましたが、 volatile int *arr = 0; で定義した arr (int へのポインタ、値は 0)に対して delete arr; とやっているのはどういうことなのでしょうか。volatile の意味は (たぶん)理解しています( volatile は型修飾子で変数の値が プログラムの外から変わることもあるから、ある種の オプティマイゼーションを拒否する)。delete は「メモリを解放 する」そうですが、"delete arr" によってポインタ arr の値はもはや 0 でなくなってしまうのですか。 次の #ifdef DYN の中の arr = new int[10]; はポインタ arr がダイナミックメモリ上にメモリを確保された int 型 の array[10] の先頭を指すようにしているんですよね。まぁ、イマイチ しっくり来ませんが良しとしましょう。 しかし、次の #else の中の volatile int arr[10]; って合法なんですか。arr が今度はポインタじゃなくて int 型の array[10] に同じ名前で宣言されているのはなぜ!? ・・・ご覧の通り、私には多くの基礎知識が欠けています。 もう少し辛抱してご指導いだだければ幸いです。課題への解答では なく、その前の理解のところをご指導下さい。よろしくお願い いたします。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

5 と 6 は簡単だな. 5: NULL を使うとコンパイラを通らないから 6: そういうことになっているから ところでこのプログラムってあやしい香りがするんですけど, C++ として正当なんでしょうか? C++ では atoi は本来 std 名前空間の中で定義され, stdlib.h を #include すると大域名前空間にも導入されます. そう考えると extern "C" int atoi( const char *str ); はセーフなのか, ちょっと気になります.

patatas
質問者

お礼

ご回答ありがとうございます。課題5は確かに NULL を使うとコンパイラが error: 'NULL' was not declared in this scope とエラーを出します。 c++ で NULL がどう定義されているかちゃんと調べたいのですが、 ググると色々な定義や解釈がでてきてしまうので困りました。 課題6の delete はまさに、そういういうことになっているからなん ですね。 また、 extern "C" int atoi( const char *str); については、この宣言によって atoi は C++ での atoi でなくて C での atoi ではないということなので、一応オーケーでしょうか。 ANo.6 の方のご回答にもあるように、移植性で問題があるので よい習慣ではないのでしょうね。

すると、全ての回答が全文表示されます。
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.4

>私の問題は、この switch 文の動作は分かるけれど、何のために あるのかが分からないという事です。 おっしゃる意味がわかりません。動作がわかるのなら、意味もわかると思うのですが・・。どのあたりがどのようにわからないでしょうか? 動作としては、コマンドラインの引数が1つあった場合、timesにその引数の値をintにして代入するということです。 timesというのは要するに繰り返し回数ですから、繰り返し回数を引数で指定できるようにして、無指定の場合は 100000000回繰り返すということでしょう。 なぜifではなくswitchなのかというと、推測の域を出ませんが、引数の数がもっと増えた場合に備えてのことではないでしょうか。それほど深い意味はないと思います。

patatas
質問者

お礼

ご回答ありがとうございました。ANo.2 のお礼の欄に書きましたように、 コマンドラインの引数として実行回数をとるということが全く分かって いなかったので、質問の仕方も不明瞭になってしまいました。 これからもよろしくお願いいたします。

すると、全ての回答が全文表示されます。
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

課題3について >コンパイラオプティマイゼーション(例えばコンパイラフラッグ -O2 など)を用いて課題1、2を行え。 コンパイラオプティマイゼーションとは、コンパイルする時に、どれだけ最適化をするかの指定です。 最適化をすると何がうれしいかというと 1.実行時間が短縮化できる。 2.メモリの使用量が減る。 等があります。(1と2は両立しない場合もあります) 今回は、実行時間の短縮だけに注目するので、 最適化のレベル(コンパイラにより異なるが、ふつう3段階くらいはあります。)を変えて、次々と時間を計測すれば、求める結果が得られるでしょう。

patatas
質問者

お礼

引き続きご回答ありがとうございました。いろいろ試して報告させて いただきます。

すると、全ての回答が全文表示されます。
  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

argc, argvはコマンドライン引数というものです。 プログラム実行時にコマンドラインにプログラム名を打ち込みますがこのときプログラム名に続けて引数を書けます。 例)$./a.out 123 例の場合argcに引数の数2が入ります(プログラム名も引数に数えるので) argv[ ] に引数の文字列のポインタが入ります argv[0]に"./a.out"、argv[1]に"123"(文字列であって数値ではないのに注意)  switch ( argc ){   case 2:    times = atoi( argv[1] );  } // switch これはプログラムが引数つきで起動された場合引数の文字列を数値に変更してtimesに代入するという動作になります。

patatas
質問者

お礼

早速のご回答、ありがとうございます。丁寧に説明して下さったのに 心苦しいのですが、説明して下さったことは理解しています。 私の問題は、この switch 文の動作は分かるけれど、何のために あるのかが分からないという事です。課題1は、DYN が定義されて いない場合の user time は 0.31 secs でしたが、DYN が定義されて いる場合の user time は 9.5 secs もかかりました。 課題2と課題3は全然アイディアがありません。詰まっています。 課題4ではnew を用いたダイナミックなメモリアロケーションは オートマティックなメモリアロケーションより時間がかかるということ だと思います。課題5、6は少し脇道でしょうか。まだ考えていません。 課題2、3のヒントを頂けたら嬉しいです。 こちらの質問が明確でなくお時間を取らせてしまい申し訳ありません でしたが早速のご回答と明快な説明をありがとうございました。 またよろしくお願いいたします。

すると、全ての回答が全文表示されます。

関連するQ&A