• ベストアンサー

C言語以外ならバッファオーバーフローは起きないのでしょうか?

こんにちわ 私はつい最近プログラミング入門したばかりのものです。 いろいろな興味に実力がついていけずとんちんかんな状態です。 ところで、昨今のセキュリティ問題でよく登場するバッファーオーバーフローという ものは何だろう、と思っていろいろ自分なりに調べてみました。 ある説明文では、C言語のメモリー格納仕様に起因する問題、と書かれていました。 ・・・ということは、パスカルなどのような他の言語であれば、バッファーオーバー フローの心配はしなくてもいいことになるでしょうか? マック愛好家の間では、MacOSの安全性の高さを大変にアピールしていますが、これは 技術的に言うとMacがPascal言語で開発されていたから、という種明かし、と考えれば よいことになりますでしょうか? お暇な方がいらしてましたら、どうかおつきあい頂けましたら幸いです。

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

  • ベストアンサー
  • ultraCS
  • ベストアンサー率44% (3956/8947)
回答No.7

#6です、話がそれて雑談というか余談に近づいていますが ちょっと誤解を招く書き方がありました、コードインタープリタというのは言語ではなく、CPUの中で命令の機械語をフェッチし、インストラクションコードに基づいたアキュムレータの動作、オペランドのアドレス変換をしてデータを取り出す機構で、CPU内部で動く一種のプログラムで、ユーザがいじることは出来ません。コードインタープリタというのも正式名称かはわかりません。 それが、次の実行命令として、インストラクションポインタで指定されたアドレスに格納されているバイト群を取り出すわけですが、このとき、それが、コードかデータかを判断できないと言うことです。 ノイマン型コンピュータでは、アドレス空間はリニアに実装され、そこを適当にコードとデータで分割して使います。この方法にはある程度のルール(低いアドレスは割り込み等のシステムコールに使うなど)はありますが、基本的にはフリーです。データがコードの前にあっても後ろにあっても構わないわけです。 Pascalも、Wirthが考えたPureなパスカルであれば別ですが、現在出回っているPascalは使いやすく(Cと対峙する為もあり)するために拡張が施されているし、実際に使うとなると、すべてを値渡しというわけにも行かず、システムとのインターフェースでは、アドレス渡しをせざるを得ません、で、ここが大きな穴になってしまいます。まあ、BASICだって、ダートマスのPureなBASICは今のBASICとは似ても似つかないものですから仕方ないでしょうけど。 ところで、バッファオーバーフローに限れば、おそらく、プログラムではライブラリで処理しているでしょうから、そのライブラリのコードに問題がある、ところが、そこを書いた人間が退社してしまってわからない。ソースが見つからないなんて事もこの業界ではざらにありますから、おそらく、そんなところではないかと思います。これを書いたプログラマは気が気じゃないだろうなあ(人ごとじゃなく、心臓が縮む思い)。

altosax
質問者

お礼

こんなに沢山詳しく、ほんとにありがとうございます!! なるほど、だんだんわかってきました! こういう図式、と思えばよいわけですね!!(^^)?? 他のご回答者さんもおっしゃるように、 1:Cは配列の境界チェックが甘いとすぐにバッファオーバーフローに直結する 2:だから丁寧なソフトハウスでは厳密に厳しいチェックをして防止に努める 3:しかしプログラマがどんなに頑張ったところでCPU機構内にノイマン式の宿命でデータとプログラムが混同される危険関門がある、 4:C以外の言語の元祖仕様はBOFの発生しない仕様だったが、オーバーヘッド等の弱点改良のためその後仕様変更され、BOFの可能性が同様に生じる仕様になってきている、 ・・・ということになりそうですね? マックファンの主張する「BOFはウインテルの問題」という論理が本当だとすれば、2の「アップルのプログラマが念入りで転出者作成ライブラリのソース引き継ぎ管理もきちんとした社内体制」+3のパワーPCがインテルよりコード解釈を忠実に行う傾向のマシなノイマン式、ということになりそうですね、 こんどは別件でアップルの社内体制や、パワーPCが非ノイマン式に近い解釈動作なのか、ということを質問してみようと思います、 ほんとに皆さんどうも有り難うございました!!! (このスレで私がわかったつもりになったこの解釈で、変なところがありましたら、またどうぞご叱正くださいませ^^お待ちしてます!)

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

その他の回答 (6)

  • ultraCS
  • ベストアンサー率44% (3956/8947)
回答No.6

一般論で書きますね ノイマン型コンピュータである限り、本質的には回避できない問題です。データとプログラムを区別しないというのも一つの特徴で、これの恩恵はOS開発などでは計り知れないものがあり、ちゃんと理解して使えば大変便利なものでした。インストラクションコードやオペランドを直接書き換えるなど、アドレス空間が小さい時代には大変重宝でした。オーバーレイモジュールなどもユーザー側で実現できましたから。 なので、OSや言語、アプリケーションが一生懸命それを防止しようとしても、最後に出てくるコードインタープリタが一切お構いなしで動いてしまうため、どこかに穴があれば簡単に漏れてしまいます。これはMacでも同じです。違うのは穴の大きさと数ということになります。 また、Macにしても、初期には、OSがPascalで書かれていたとしても、BIOSに当たる部分、ToolBoxやデバイスドライバには68Kネイティブのアセンブラで書いた部分があり、ここでは、同様の問題があり得ました(最近のMacは詳しくないので)。 データフローマシンなど非ノイマン型に期待するしかないかも知れません。実際、アドレス空間が広がった状況では、コードとデータを完全分離することは不可能ではありません。

altosax
質問者

お礼

どうもありがとうございます! >データとプログラムを区別しないというのも一つの特徴で、これの恩恵 なるほど、バッファーオーバーランの悪用という基本の考え方はここに帰結して いるということなんですね^^ >OSや言語、アプリケーションが一生懸命それを防止しようとしても、最後に出てくるコードインタープリタが一切お構いなしで動いてしまうため これはとても興味深いお話をうかがいました! ちょっとかみくだいていただけると嬉しいのですが、 #2&#3のみなさまからお寄せいただいたご回答では、配列の境界チェック を厳密に実施することで未然に防げる(不注意による人災)という主旨で私は 理解したつもりになっていたのですが、コードインタープリターのコンパイラ が、せっかくの厳密な配列の境界のチェックも台無しにしてしまう、という 危険性をノイマン型コンピュータの宿命として持っているということ? になるのでしょうか? わたしはどんなに頑張っても趣味の日曜プログラマまでで終わりそうですが、 概念的な意味では、このあたりが、非常に気になってしまうんです。 >BIOSに当たる部分、ToolBoxやデバイスドライバには68Kネイティブのアセンブラで書いた部分があり なあるほど、また心当たりがありました。 iMac以後のモデルでは、ハードのBIOSが完全に無くなってToolBoxもハードディ スクに格納されるようになったんです(NewWorldMacと分類されています) この問題に起因する事故の防止という意味もあったのかもしれません。 >実際、アドレス空間が広がった状況では、コードとデータを完全分離することは不可能ではありません。 これはありがたい希望の光ですね!

全文を見る
すると、全ての回答が全文表示されます。
noname#12761
noname#12761
回答No.5

古典的なパスカルの仕様ならバッファーオーバーフローは発生しないかもしれません。 しかしそれでは OS は開発できません。当然ポインタが使用できインラインアセンブラが使えるような拡張された仕様でないと開発はできません。 そうなれば、C,C++ とほとんど条件は変わりません。 また Mac は Unix 指向に向かっていますので関数呼び出しの仕様の違いなど考えると Pascal で開発すると逆にバグが増えそうです。 TT414 さんの >OSX以前はPascalだったかもしれませんが、OSXはCです(unix系なので) との指摘は理にかなっています。

altosax
質問者

補足

どうもありがとうございます、 ちょっとまだ私のレベルでは飲み込めない話なのですが、PascalではOS開発ができない前提ですと、最初のマックがPascalで開発云々、という話は技術的にありえないファンの創作した「神話」のひとつ、となるでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • TT414
  • ベストアンサー率18% (72/384)
回答No.4

>MacがPascal言語で開発されていた OSX以前はPascalだったかもしれませんが、OSXはCです(unix系なので)。

altosax
質問者

補足

どうもありがとうございます。 この辺の事情を私も知りたいのですが、ご存知の方いらしてましたら続報を いただけましたら幸いです。 多分漢字トーク7時代にはCに移行していたのではなかろうか?というフィーリング で私は想像している(多種類のプログラミング環境が揃っていたので)のですが いかがでしょうか、どうぞ皆様よろしくおねがいします!

全文を見る
すると、全ての回答が全文表示されます。
回答No.3

>ある説明文では、C言語のメモリー格納仕様に起因する問題、と書かれていました。 この説明は適切ではないと思いますよ。 「C言語のメモリー格納仕様を鑑みず、無頓着なプログラミングにより発生する問題」と するのが良いかと思います。 バッファオーバーフローの原因を、C言語に押しつけてしまうのは、如何なものかと。 >・・・ということは、パスカルなどのような他の言語であれば、バッファーオーバー >フローの心配はしなくてもいいことになるでしょうか? 現代のpascal系の言語で、バッファオーバーフローが起こらないわけではありません。 ポインタを使う場面は多々あるので、同じような問題は引き起こす可能性を持っていると 考えたほうが良いと思います。

altosax
質問者

お礼

早速にどうもありがとうございます! >この説明は適切ではないと思いますよ。 >「C言語のメモリー格納仕様を鑑みず、無頓着なプログラミングにより発生する問題」と >するのが良いかと思います。 なるほど、そういうことだったんですね! そうすると、マックファンの方々がマイクロソフトのプログラムを罵倒するのは 単なる身びいきの発言ではなく、ますます現実を冷静に直視した結果の杜撰さの 指摘、ということになりそうですね。 これはマイクロソフトには本当に真剣に抜本的に考え直してもらわないと困る問題ですね! >現代のpascal系の言語で、バッファオーバーフローが起こらないわけではありません。 >ポインタを使う場面は多々あるので、同じような問題は引き起こす可能性を持っていると >考えたほうが良いと思います。 なるほど、パスカルゆえの安全の確保、というのは昔話になってきているのですね! どうもありがとうございました!!

全文を見る
すると、全ての回答が全文表示されます。
  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.2

No.1さんはOSの不備と言っていますが、多くのバッファオーバーフロー攻撃はOSの用意したバッファじゃなくアプリケーションが用意したバッファを溢れさせてアプリケーションを乗っ取るものです。もしOSの用意したバッファが溢れたらカーネルごと乗っ取られますよ。(^-^;) バッファオーバーフローに関してOSが不備な点は多くはスタック上にあるバッファ溢れ部分でプログラムが実行できてしまうことくらいです。プログラムとデータを区別してアクセス権管理ができていれば多くの場合は防げるんですからね。 # ただOSがCPUサポートなしに管理するのは大変なので最近のCPUではNXビットなんてものが追加されていたりする ちなみにバッファオーバーフローは配列の境界チェックをきちんとやっていれば防げます。C言語では全く無チェックなのでa[-1]なんて無茶もできるわけですが、Pascalや最近ではJavaなど多くの言語では宣言範囲外の配列インデックスではアクセスできないようになっています。 ただ配列インデックスのチェックは実行時のオーバーヘッドになるため、C言語では採用されていないということです。

altosax
質問者

お礼

さっそくに沢山のご回答を寄せていただき感謝感激です! >もしOSの用意したバッファが溢れたらカーネルごと乗っ取られますよ。(^-^;) あっはあ!そういうことですねえ(^^;) >ちなみにバッファオーバーフローは配列の境界チェックをきちんとやっていれば防げます なるほど、アップルファンのみなさんが、マイクロソフトのプログラミングは 杜撰でアップルのプログラマはきちんとしている、という論拠はこの辺にあり そうですね! >Pascalや最近ではJavaなど多くの言語では宣言範囲外の配列インデックスではアクセスできないようになっています。 なるほどなるほど、Javaが言語仕様からして安全だ、と言われている理由も疑 問だったのですが、これで謎が解けました! MacOSではバッファーオーバーフローは起きない、というのはPascalの仕様から 言って本当だったんですね! >実行時のオーバーヘッドになるため これまたなるほど納得です! マックが歴史的にOSが単純な割に非常に重かったのは、そのせいもあった訳で すね。

全文を見る
すると、全ての回答が全文表示されます。
  • OsieteG00
  • ベストアンサー率35% (777/2173)
回答No.1

C言語に限った話ではないですが、C言語では任意のアドレスのメモリにアクセスできるのでそういう説明になりましたかね。 結局、PascalであってもCであってもコンパイルすれば同じですから、言語による違いというものはありません。また、メモリの格納仕様は処理系(OS)によって異なります。言語仕様によるものというよりは、OS上の不備を突いた攻撃です。OSが用意したバッファより大きいデータ量を送りつけて、バッファより大きい部分のデータをプログラムとして認識させて誤動作させるというしくみです。 Macの安全性については、単にシェアが低くてかつ内容がブラックボックス化しているのでハッカーの興味を引かなかったという事ですね。

altosax
質問者

お礼

さっそくにどうもありがとうございます!! >C言語では任意のアドレスのメモリにアクセスできるのでそういう説明 なるほど、たしかに私の見た説明文も前段としてそのように書かれていました! >結局、PascalであってもCであってもコンパイルすれば同じ なんと、コンパイル後は関係ない話だったのですね^^; おかげさまでわかりました! >OSが用意したバッファより大きいデータ量を送りつけ >ハッカーの興味を引かなかったという事ですね ・・・するとMacに向けて悪い巨大データを送れば理論上はWindowsとおなじく バッファーオーバーフロー攻撃が成立してしまう、ということですね? (しかし実務的にどういう手順で攻撃すればよいか関心が持たれていない、 ∴結果的に今のところ安全、と。) この点については、「できるものならどうぞやって下さい!」と懸賞コンテスト などが行われようとした経緯もありますので、とても気になるところです。 どうもありがとうございました!

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

関連するQ&A

  • C言語について

    C言語を学習しています。 入門レベルの知識しか有りません。 <演習問題>  要素数nの配列v内のkeyと等しい全要素の添字を配列idxに格納する  関数search_idxを作成せよ。  返却するのはkeyと等しい要素の個数とする。   int search_idx(const int v[], int idx[], int key, int n); 例えば、vに受け取った配列の要素が{1,7,5,7,2,4,7}でkeyが7で     あれば、idxに{1,3,6}を格納した上で3を返却する。 というのが有るのですが、上手くプログラムが組めません。 ソースコードを伝授して頂けたら有難いです。

  • バッファオーバーフローについて

    プログラムを書き換えてないでmakeし実行すると バッファオーバーフローになったりならなかったりします。 なぜでしょうか? 大きなプログラムは書いていません。 OS:windows7 visual studio2005

  • バッファオーバーフローについて

    いつもお世話になっております。 最近、WINDOWSでバッファオーバーフローの脆弱性が発見されましたが、 これって、外界と繋がっていない専用線のシステムには影響はないと考えていいんでしょうか? 認識として外界と接続しているWINDOWSのセキュリティホールの一つであって 対策は、バッチファイルを当てることを各HPで読みましたが、24時間動いてる物だと再起動できないので当てられないと判断して、現状としてはFWで不正アクセスを防ぐことしかできないのではと考えていますが、私の認識は間違っているでしょうか? 文章分かりにくくてすいませんがお願いします。

  • バッファオーバーフロー

    動画形式DivxからAviに拡張子を変更したり、その変更した動画を再生しようとすると、マカフィーがバッファオーバーフローを検知するんですが、何故でしょうか? 動画はstage6で落としたものなんですが、そこの他の動画で試してみても同じく検知されました。 普通に再生できるので動画ファイル自体は問題ないはずなんですが。

  • バッファーオーバーフローを防ぐには?

    以前ここで質問し、バッファーオーバーフローがメモリーの関係で怒るものだと分かりました。 ですが、どうすればバッファーオーバーフローを防ぐことが出来るのかさっぱりわかりません。 一応ネットでも調べたのですが、パソコンに弱くさっぱり分かりませんでした。 どう対処すればいいのでしょうか? 教えていただけたらと思います!

  • バッファのオーバーフロー

    とあるサイトを実行すると、「バッファオーバーフロー保護によりブロックされました」と出てしまうので、そのサイトが使えません。何か良い解決法はあるのでしょうか?

  • バッファオーバーフロー

    バッファオーバーフローとは何でしょうか? 検索フォームに長文の文字を検索すると誤作動が起きてしまうものなのでしょうか? 例えば10文字以内で検索という条件がある時、 「犬も歩けば棒に当たる 対義語」と検索して 文字数がオーバーになって誤作動が発生する物なのでしょうか?

  • バッファーオーバーフロー!?

    最近ネットで動画とかを配信しているサイトをよく開くのですが。 毎回バッファーオーバーフローというものが出て途中で「応答なし」になって固まってしまいます。 たとえそのページ以外何も開いていなくても、バッファーオーバーフローになってしまいます。 ウィルスソフトはMcAfeeを使ってます。 なぜなんでしょう? なぜ起こるのか、対策とか、防ぐ方法とかご存知の方、教えてください! エラーの詳細を見ても分からないんです…

  • C言語のオーバーフローについて

    csvからデータを読み取り、計算させるプログラムで、行が多くなると「StuckOverFlowReception」と表示されます。静的に領域を確保していることに原因があるような気がするのですが、どこがオーバーフローしているのか、どう直せばよいのかがわかりません。改善のご指摘をお願いします。 VisualStudio2010をwindows7で使用しています。プログラム初心者なので、かなりみにくいかもしれません。すいません。ちなみに15行ぐらいにするとオバーフローと表示されます。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define N 20//行数の定義 #define M 2048//列数の定義 int main() { char *fname = "ttt.csv"; //読み取り用ファイル char *ffname = "tk.csv"; //読み取り用ファイル FILE *IN1, *IN2, *OUT1, *OUT2; char buff[30000]; //配列を静的に確保(桁が大きいので、大きくとっています) char *pbuff; //読み取ったデータを格納する用 char arv[600]; //ffnameの配列用 char *parv; //arv[]の格納用 double a[N][M+30], b[N][M], c[N][M], w[4][32]; //配列の領域を定義 int i, j, x; //for文の繰り返し用 double m, n; //計算結果の一時的な格納用 if((IN1 = fopen(fname, "r")) == NULL){  ////ファイルを開く↓ printf("can't open the %s", fname); return 0; } if((IN2 = fopen(ffname, "r")) == NULL){ printf("can't open the %s", ffname); return 0; } if((OUT1 = fopen("high wavelet.csv", "w")) == NULL){ printf("can't open the ha.csv"); return 0; } if((OUT2 = fopen("low wavelet.csv", "w")) == NULL){ printf("can't open the la.csv"); return 0; }                         ////ファイルを開く↑ i=j=0; //配列の取得↓ while(fgets(buff, 30000, IN1) != NULL){ //csvデータ1行読み込みの繰り返し pbuff = buff; while((pbuff = strtok(pbuff, ",\n")) != NULL){ //pbuffのデータを区切る a[i][j++] = strtod(pbuff, NULL); //,をとばして配列に格納 pbuff = NULL; } i++; j=0; } i=j=0; //上の作業と同じ↓ while(fgets(arv, 600, IN2) != NULL){ parv = arv; while((parv = strtok(parv, ",\n")) != NULL){ w[i][j++] = strtod(parv, NULL); parv = NULL; } i++; j=0; }          ///ここまででcsvを配列に格納完了 x=0;                //計算上必要な       for(i=0; i<N; i++){         //作業をしてる for(j=0; j<30; j++){    //だけなので、ここは a[i][M+j] = a[i][j];//無視してください } } for(i=0; i<N; i++){        //ここから実際の計算 for(j=0; j<M; j++){  //計算長くてすいません m = (a[i][j]*w[0][0] + a[i][j+1]*w[0][1] + a[i][j+2]*w[0][2] + a[i][j+3]*w[0][3] + a[i][j+4]*w[0][4] + a[i][j+5]*w[0][5] + a[i][j+6]*w[0][6] + a[i][j+7]*w[0][7] + a[i][j+8]*w[0][8] + a[i][j+9]*w[0][9] + a[i][j+10]*w[0][10] + a[i][j+11]*w[0][11] + a[i][j+12]*w[0][12] + a[i][j+13]*w[0][13] + a[i][j+14]*w[0][14] + a[i][j+15]*w[0][15] + a[i][j+16]*w[0][16] + a[i][j+17]*w[0][17] + a[i][j+18]*w[0][18] + a[i][j+19]*w[0][19] + a[i][j+20]*w[0][20] + a[i][j+21]*w[0][21] + a[i][j+22]*w[0][22] + a[i][j+23]*w[0][23] + a[i][j+24]*w[0][24] + a[i][j+25]*w[0][25] + a[i][j+26]*w[0][26] + a[i][j+27]*w[0][27] + a[i][j+28]*w[0][28] + a[i][j+29]*w[0][29] + a[i][j+30]*w[0][30] + a[i][j+31]*w[0][31]); n = (a[i][j]*w[1][0] + a[i][j+1]*w[1][1] + a[i][j+2]*w[1][2] + a[i][j+3]*w[1][3] + a[i][j+4]*w[1][4] + a[i][j+5]*w[1][5] + a[i][j+6]*w[1][6] + a[i][j+7]*w[1][7] + a[i][j+8]*w[1][8] + a[i][j+9]*w[1][9] + a[i][j+10]*w[1][10] + a[i][j+11]*w[1][11] + a[i][j+12]*w[1][12] + a[i][j+13]*w[1][13] + a[i][j+14]*w[1][14] + a[i][j+15]*w[1][15] + a[i][j+16]*w[1][16] + a[i][j+17]*w[1][17] + a[i][j+18]*w[1][18] + a[i][j+19]*w[1][19] + a[i][j+20]*w[1][20] + a[i][j+21]*w[1][21] + a[i][j+22]*w[1][22] + a[i][j+23]*w[1][23] + a[i][j+24]*w[1][24] + a[i][j+25]*w[1][25] + a[i][j+26]*w[1][26] + a[i][j+27]*w[1][27] + a[i][j+28]*w[1][28] + a[i][j+29]*w[1][29] + a[i][j+30]*w[1][30] + a[i][j+31]*w[1][31]); b[i][x] = m; //配列×配列をしてm、nに一時的に格納し c[i][x] = n; //新たな配列に入れてます x++; j++; } x=0; } for(i=0; i<N; i++){       //ここから新たに得た配列をcsvに書き込んでいます for(j=0; j<(M/2); j++){ fprintf(OUT1, "%e", b[i][j]); fprintf(OUT2, "%e", c[i][j]); if(j==(M/2-1)){ fprintf(OUT1, "\n"); fprintf(OUT2, "\n"); }else{ fprintf(OUT1, ","); fprintf(OUT2, ","); } } } fclose(IN1); fclose(IN2); fclose(OUT1); fclose(OUT2); rewind(stdin); getchar(); return 0; }

  • 加減剰余のオーバーフローについて

    今C言語で加減剰余のプログラムを作っていて、 オーバーフローのチェックだけが上手くいきません。 limits.hをインクルードして、オーバーフローのチェック を行いたいのですがどうすればよいのでしょうか? 扱いたい範囲はint型の-2147483648~2147483647です。 ちなみに開発環境はvc++2005です。 一応ソースを載せておきますので、よろしくお願いします。 #pragma warning ( disable : 4996 ) #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <limits.h> int main ( int argc, char *argv[] ) { int start; // 最初に入力する値(引数1) int end; // 最後に入力する値(引数3) int kekka; // 計算結果を格納 int amari; // 除算の余りを格納 int max = INT_MAX; // 表すことが出来る最大値 int min = INT_MIN; // 表すことが出来る最小値 char enzansi; // 入力する演算子 (引数2) char str1[512]; // 格納用の配列を宣言(start用) char str2[512]; // 格納用の配列を宣言(end用) /* 引数の個数チェック */ if ( argc != 4 ) { printf ( "usage : %s start enzansi end\n", argv[0] ); exit ( 0 ); } /* 引数を取得して整数型に変換 */ start = atoi ( argv[1] ); end = atoi ( argv[3] ); /* 引数の取得 */ enzansi = ( argv[2][0] ); sprintf ( str1, "%d", start ); // str1に値を格納 sprintf ( str2, "%d", end ); // str2に値を格納 /* str1とargv[1]による文字列の比較 */ if ( strcmp ( str1, argv[1] ) ) { printf ( "error : 整数を入力して下さい。\n" ); exit ( 0 ); /* str2とargv[3]による文字列の比較 */ } else if ( strcmp ( str2, argv[3] ) ) { printf ( "error : 整数を入力して下さい。\n" ); exit ( 0 ); /* argv[2]が2文字以上の場合 */ } else if ( strlen ( argv[2] ) >= 2 ) { printf ( "error : 演算子を正しく入力して下さい。\n" ); exit ( 0 ); } /* 入力された演算子の条件ごとに計算 */ if ( enzansi == '+' ) { kekka = start + end; } else if ( enzansi == '-' ) { kekka = start - end; } else if ( enzansi == '*' ) { kekka = start * end; } else if ( enzansi == '/' ) { /* startの値を0で除算する場合 */ if ( end == 0 ) { printf ( "error : 0による除算は禁止です。\n" ); exit ( 0 ); } kekka = start % end; // 剰余を求める /* 割り算の結果として余りが出なかった場合 */ if ( kekka == 0 ) { kekka = start / end; printf ( "%d %c %d = %d", start, enzansi, end, kekka ); exit ( 0 ); /* 割り算の結果として余りが出た場合 */ } else if ( kekka != 0 ) { kekka = start / end; amari = start % end; printf ( "%d %c %d = %d余り%d", start, enzansi, end, kekka, amari ); exit ( 0 ); } /* 入力された演算子が異なる場合 */ } else { printf ( "error : '+' '-' '*' '/'のいずれかの演算子を入力して下さい。\n" ); exit ( 0 ); } /* 数値1 演算子 数値2 = 演算結果の形式で出力する */ printf ( "%d %c %d = %d", start, enzansi, end, kekka ); exit ( 0 ); } もし変な部分がありましたら指摘お願いします。 一応四則演算は問題なくできます。