- ベストアンサー
最初から・・・・
現在C++を学んでいる身です。 あるサイトを参考に学習しているのですが、以下に示すサイトで躓きました。 http://www5c.biglobe.ne.jp/~ecb/cpp/cpp00.html 自分は逆ポーランド表記は学習済みなのでそれ自体は理解できます。 それに以前C++をあるサイトで一通り学習はしたのですが、やりたりなくて現在も上のサイトを参考にさせてもらっています。 上で示すサイトに逆ポーランド表記についての計算プログラムがC++によって書かれています。 以下はそのプログラムについての質問をしていきます。 まずStack.hとmain.cppに分かれていますが、Stack.hの内容は理解できるのですが、main.cppで疑問がでてしまいました。しかも最初からです。 まず IntStack ostack( argc - 1 ); と記述していますが、これはIntStackクラスをostackでインスタンス化を行っています。 しかし、ここでコンストラクタが呼ばれますが、IntStackクラスのコンストラクタは最初から引数に指定がされているため、このように記述した場合どのような動作を行うか予想がつきません。 それにこの記述では argc - 1 となっていますが、 まずargcには何が入っているのでしょうか?そこから不明です。 次にこのプログラムは外部から逆ポーランド表記で入力したものを計算することが目的にもかかわらず、キーボードからの入力部分が見つからないのですが、どこで行っているのでしょう? この2つの疑問がでてきてしまったのですが、最後にもう1つ発生してしまいました。 それはこのプログラムを全てコピーしてもスタックの整合性確認の部分のエラーメッセージが表示されてしまい、実行することができません。どうしてなのでしょう? 環境は Visual Studio 2005.net C++です。 よろしくお願いします
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
★追記。 ・コンストラクタには引数なしと引数が複数あるタイプを同時に複数個、定義できます。 C++ では同じ関数名でも引数の型、個数が違うと別の関数が呼ばれる仕組みになっています。 これを『オーバーロード』といいます。 前回、紹介した C++ 入門の何処かに解説ページがありますよね。 ここですね。→http://www5c.biglobe.ne.jp/~ecb/cpp/03_08.html なお、デストラクタは1つしか定義できません。引数もありません。 ・また、C++ では宣言部に初期値を設定できます。 func( int value=100 ); となっていると func(); として引数を省略して呼んだ場合に func( 100 ); と呼び出したときと 全く同じになります。C 言語では引数の初期値を設定できませんでしたが、C++ では便利な機能が 追加されています。多用すると混乱しますので適度に使い分けましょう。 ・また、オーバーロードも戻り値が違う型でも引数が同じだと関数の区別が出来ません。注意! 前回紹介したリンクも一読しておくと良い。 http://www.cmagazine.jp/src/kinjite/cpp/index.html→『プログラミングの禁じ手Web版 C++編』 ・以上。おわり。
その他の回答 (4)
- Oh-Orange
- ベストアンサー率63% (854/1345)
★argc、argv について ・既に回答がありますが、次の質問も参考にして下さい。 ・http://oshiete1.goo.ne.jp/qa2947615.html→『コマンドとコマンドラインとコマンドラインオプションの違いを教えてください。』 argc は、コマンドラインの引数の個数 argv は、コマンドラインの引数の配列(文字列ポインタへの配列) argv[ argc ] は必ず NULL ポインタが入っている。など。 ・思い違いかな。 >次にこのプログラムは外部から逆ポーランド表記で入力したものを計算することが目的にもかかわらず、 >キーボードからの入力部分が見つからないのですが、どこで行っているのでしょう? 最初からキーボードの入力は想定していません。 プログラムの引数を処理しています。→argv[i] です。 つまり、コンソール画面でプログラムに指定した引数から逆ポーランド表記の計算を行って >// 答を出力する >ostack.pop( &value ); >cout << value << endl; ↑で計算結果を出力しています。 ・また >Stack<double> ostack( argc - 1 ); ↑でスタックに積み上げる数を引数カウントから指定しています。 argc はコマンドラインの引数の個数ですが、プログラム名も含むために1つ引いています。 上記のリンクより。 ・解説付きソースもどうぞ。 int main( int argc, char *argv[] ) ←コマンドラインを受け取るお決まりの記述 { double value; ←計算結果 double operand1; ←値1 double operand2; ←値2 // スタックテンプレートクラスから、実数スタックを具体化する Stack<double> ostack( argc - 1 ); ←(引数の個数-1)のスタック領域を用意。 // コマンド行引数からリバーシュポーリッシュ記法で記述された式を // 読み込み計算する for ( int i = 1 ; i < argc ; i++ ){ ←コマンドラインの引数分ループ処理する // 加法 if( strcmp( argv[i], "+" ) == 0 ){ ostack.pop( &operand2 ); ←値2 を pop する ostack.pop( &operand1 ); ←値1 を pop する ostack.push( operand1 + operand2 ); ←加算 } : 省略 : // 上記以外は整数を仮定する else{ value = atof( argv[i] ); ←演算子以外は『数』とする ostack.push( value ); ←単純に push している } } // スタックの整合性の確認 if ( ostack.get_length() != 1 ){ ←push、pop の整合性チェック cerr << "illegal expression" << endl; return 1; } // 答を出力する ostack.pop( &value ); cout << value << endl; ←計算結果を表示 // 正常終了 return 0; // ostack がスコープから抜ける時、自動的にデストラクタが // 呼び出される } 最後に: ・重要なのは argc、argv がコマンドラインの引数で、それを処理しているサンプルです。 決してキーボードから入力した逆ポーランド記法の文字列を扱っていません。 よって、キーボードから入力は見つからなくて正解です。 ・以上。おわり。
- Interest
- ベストアンサー率31% (207/659)
こんばんは。 > IntStackクラスのコンストラクタは最初から引数に指定がされているため 新しいC++は、デフォルト引数を取ることができます。例えば、 void print( int n = 10 ){ cout << n << endl; } と書いてあったら、print() で呼び出せば n にはデフォルトで10が入り、print(5)で呼び出せば n には 5 が入って関数が呼び出されます。それが今回はコンストラクタに出てきた。 > まずargcには何が入っているのでしょうか? メイン関数がどうやって始まるか、よく観察してみましょう。 int main(int argc, char *argv[]) って書いてありませんか? この argc です。この argc, argv はホスト環境(OS)で、プログラムの処理開始時に、どこかで決定された情報をC言語で書かれたプログラムに伝えるために用意された引数です。なので、値はOSが入れてくれます。 argc, argvの意味については下記URLを参照して下さい。 http://okuyama.mt.tama.hosei.ac.jp/unix/C/slide67-1.html > このプログラムは外部から逆ポーランド表記で入力したものを > 計算することが目的にもかかわらず、キーボードからの入力部分 > が見つからないのですが、どこで行っているのでしょう? その答えが、argc, argv で分かっていただけましたか?
お礼
返答ありがとうございました。 解説も細かくとても分かりやすかったです。 参考URLも分かりやすく、今頃になってつける知識ではないですが、ためになりました。 ありがとうございました。
- ddnp009
- ベストアンサー率25% (15/58)
そのサイトのどこで "IntStack" が使われているか 示してほしいと思います。 それらしいのは、 http://www5c.biglobe.ne.jp/~ecb/cpp/04_07.html でしょうか。 だとしたら、 Stack( int sz = 100 ){ ・・・ } がありますね。 >IntStackクラスのコンストラクタは最初から引数に指定がされている むしろオブジェクトの構築には、通常、引数を与えるものです。 その値でオブジェクトを構築(コンストラクト・初期化)するのがコンストラクタの仕事。 >このように記述した場合どのような動作を行うか予想がつきません。 今まで引数を取らないものしか触れてこなかったのですか? だとすると、"通常の"コンストラクタを勉強するよい機会です。 新しいことを覚えられますよ。わくわくするでしょう? >この記述では argc - 1 となっていますが、 まずargcには何が入っているのでしょうか? ??? argcとはなんぞや?ということですか? もしそうなら、クラス云々の前に C/C++の基本を勉強してください。
お礼
返答ありがとうございました。 URLがうまく貼り付けられていなかったらしく、ご迷惑をおかけしました。 このページが2分割されており、ページを変えても表示してあるURLが変わらないことに気がつきませんでした。 申し訳ないです。 前々からC言語のみ勉強をし、その中で引数は func(int x) などの値のみのプログラムしか見てきませんでしたが、func(int x = 10)などと行う場合はデフォルト指定になるんですね。またコンストラクタで指定する場合は、その指定が優先されて反映されるということですね。 ありがとうございました。
- koko_u_
- ベストアンサー率18% (459/2509)
>IntStackクラスのコンストラクタは最初から引数に指定がされているため、 >このように記述した場合どのような動作を行うか予想がつきません。 単純に IntStack::IntStack(int sz) を呼出しているだけですが。 argc はもちろん引数の数です(プログラマの常識)プログラム名自体も引数の数に含まれるので 1 引いています 実行例で「clac 15 10 - 3 *」とした時には、argc = 6, argv[] = {"calc", "15", "10", "-", "3", "*" } と初期化されます。
お礼
返答ありがとうございました。 常識がなくて申し訳ない・・・・ いままでC言語でコマンドラインから実行したことがなかったもので、プログラムを見たときちんぷんかんぷんでした。 Javaならコマンドラインからの実行を行ったことがあるのですが・・・ ありがとうございました
お礼
返答ありがとうございました。 長々とソースの解説まで頂き感謝します^^ とても分かりやすかったです。 No2の回答者さんのお礼にも書きましたが、今までコンパイラの方で実行のみ行ってきてしまって、コマンドラインからの実行は行ったことがなく皆無でしたorz(言い訳になりませんが・・・・) ありがとうございました。 また疑問が出てきたらよろしくお願いします。
補足
すいません お礼に間違いがありましたw No1の回答者さんのお礼に書きました。