web-dev-qa-db-ja.com

C ++コードでC式を使用するのは良い習慣ですか?

学校では、クラスをはるかに上回っているという事実にもかかわらず、今年Cの学習を開始しました。クラスがCのベースにある間に、Java、C++、およびCを学びました。とにかく、自分自身を文書化し、本を読んでいます。記事、そしてなぜ私はCを学ぶべきなのかを先生に尋ねました、そして彼女はそれがC++の基礎であると言いました。最初にプログラミングを始めたとき、C++の方がはるかに簡単だと思いました。後でCを学びました。しかし、本では、CコードはC++で機能しますが、逆は機能しません。

私の質問はかなり単純明快です〜C++でC式を使用するのは良い習慣ですか?例を挙げましょう。

このコードは

#include <stdio.h>
#include <iostream>

int main() {
int x;
scanf("%d", &x);
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

これよりも効率的またはより良い方法:

#include <iostream>

int main() {
int x;
cin >> x;
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

私はすでにほこりっぽい古い本でこれに関するいくつかの簡単なドキュメントを作成しました、そして私が見つけたものから、coutの代わりにscanfを使用すると、ストリームなどがフラッシュされるので、scanfを使用して、どのようなコンテキスト。

これは、ファイルにも当てはまりますIO私はいつもFIle IOがC++よりもCの方が簡単であることがわかりました。この質問は、ほとんどすべての一般式に当てはまります。 CをC++に適用しました。最新のコンパイラを使用していることも注目に値しますが、C++コードでC式を使用するのが良いプログラミング習慣であるかどうかを尋ねているので、これは問題になりません。

これを実行することの短所と長所はおそらくありますが、私は「はい/なぜ」、「いいえ/なぜ」のタイプの答えのみを探しています。

また、詳細が残っている場合はコメントを投稿します。

19
Bugster

いいえ、それは悪い習慣です。生活のためにこれを行うと、チームが遵守しているスタイルガイドに違反することになります(または、少なくともコードレビュー中にハッキングされます)。

はい、動作しますが、同等のC++がある場合は、それを使用してください。 (例:printfscoutsを混在させないようにしてください)

36
jglouie

一般に、CとC++は、2つの完全に別個の言語であるかのように扱われます。したがって、C++プログラムでC構文を使用するのは不適切な形式と見なされる場合があります。

あなたは正しいです;ただし、そのCコードは問題なくコンパイルされます。これは、以下の基準に関して、会社がどの程度柔軟かによって異なります。面接で質問された場合は、CがC++で機能すること、およびCとC++は2つの別個の言語であることを面接担当者に必ず伝えてください。そうするための正当な理由。

考慮すべきもう1つのことは、標準は、より多くの人々がコードを簡単に操作できるプラットフォームの作成に役立つということです。幸運にも、Cを学ぶように勧めた先生がいましたが、誰もが幸運であるとは限りません。したがって、C++プログラムでCを混在させると、Cを学習したことがない人を混乱させる可能性があります。

要約すると、何かを実行できるからといって、実行する必要があるわけではありません。

20
jmort253

C++は仕様によりCと下位互換性があるため、通常CコードはC++コンパイラーによって正常にコンパイルされます(通常C++にはCにはない追加の予約語​​があり、Cコードで使用してコンパイルを中断できるため)。

しかし、私はそれをミキシングコードの悪い習慣と見なしています。 scanfを使用している場合-printfを使用し、operator >>を使用している場合はoperator <<を使用します。理由は、オーバーロードされたC++オペレーターが気づいていない機能をカプセル化する可​​能性があり、それらを不一致にすると、プログラムが望まないことをプログラムが実行してしまうためです。

C++コードでC構文を使用する特別な理由はありません。これらは異なる言語であり、C++コードでC構文を使用する場合は、C++コードを作成しているだけで、その強力なツールの多くを使用していません。

10
littleadv

コーディングスタイルと美的問題を別にすると、C++コードでCを使用するときに直面するさまざまな技術的な問題もあります。

  • Cとは? C90、C99またはC11?使用しているC標準に応じて、さまざまな互換性の問題が発生する可能性があります。ブール型、//コメント、VLAなどのC99機能、指定された初期化子など。

  • C++の型付けはCよりも厳密です。C++でCコードをコンパイルするには、さまざまな型キャストを追加して、期待される型を取得する必要があります。つまり、C++で機能させるには、完全に細かく、プロダクション品質のCコードを書き直す必要があるかもしれません。

  • より厳密なタイピングによって行われる型キャストは、一般的には良いことですが、場合によっては、バグを導入したり隠したりすることもできます。例として、malloc()の結果の悪名高いキャストを取り上げます。これはC++では型キャストする必要がありますが、Cでは決してキャストしないでください。(1)

  • CとC++の機能を混在させると、バグや未定義の動作が発生する可能性があります。たとえば、malloc()で割り当てたり、deleteで解放したりすることはできません。 (2)

  • スレッドセーフティの問題。 C標準ライブラリはスレッドセーフではありません。標準のC++ライブラリはスレッドセーフである場合とそうでない場合があります。その場合、コードにCライブラリ関数呼び出しを追加するとスレッドセーフになります。

    Windowsプログラマーへの補足として:Windows API CreateThread()関数がCライブラリと同じプログラムで使用されたとき、Visual C++コンパイラにはかなり長い間リークバグがありました。 (3、4)

  • 一部のコンパイラでは、呼び出し規約が問題になる可能性があり、extern "C"を使用して、「C呼び出し規約」とリンクする必要がある関数を明示的に通知する必要があります。

  • 迷惑な詳細。カンマ演算子の動作は異なります。 C99/C11ではstruct/enum宣言の末尾のコンマを使用できますが、C++では使用できません。さまざまな種類の変数と関数のスコープは異なる方法で処理されます。など.

さらに多くのケースが存在する可能性があります。


参照:

  1. http://c-faq.com/malloc/cast.html
  2. http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.
  3. http://www.flounder.com/badprogram.htm#CreateThread
  4. http://msdn.Microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx
9
user29079

C++がCをコンパイルできる理由は、「後方互換性」のためだけです(既存の作業コードを書き直すことは避けてください)。

しかし、C++はcとは異なる哲学を持っています。それらを混同しても、両方に良いサービスを提供することはできません。

CおよびC++がI/Oを管理する方法は、I/Oの内部状態を管理する別の方法に依存する場合があります。したがって、少なくとも入力と出力は一貫して使用してください。

そしてC++プログラムでは、C++スタイルを尊重します(他の場所で特別に行う必要がない限り)

7

Cを最初に学ぶことは、私見では良い考えだと思います。このようにして、人々はソフトウェアを作成するハードウェアを理解し始めます。

ただし、これらの2つの言語を混在させることは必ずしも良い考えではありません。 Cに共通の生のビットいじりと相まって、C++のめちゃくちゃな複雑さを得るからです。

ご覧のように、ごく単純な例でも、さまざまなタイプのストリームと内部バッファリングで同期の問題があります。しかし、C&C++アプローチは、いかなる方法でもこれ以上柔軟ではありません。クラスxに切り替えます。ストリーミングなどを使用するオペレーターはありません。

それは複雑です...

優れたC++プログラマーは、ビットがすべての構成要素の背後でどのように反転されるか、および隠された動作は何かを知っているべきだと私は本当に思います。

しかし、C++を学習するには、少なくともその50%以上で、5年以上の専門的なコーディングが必要であり、6か月のカリキュラムでは、20時間程度の実務経験でそれを管理することはできません。

CでC++構造を使用する場合、ストリームは使用しません。それらは鳥瞰図から単純化する方法であり、ソフトウェア開発は簡単であると人々に信じ込ませますが、多くの状況で多くの利点なしに余分な複雑さを隠します。

ただし、RAIIラッパークラス、テンプレート、オーバーロード、constの正確性、および一般的なインターフェイスの純粋な抽象クラス(f-ng Javaここで使用してください!)は適切な候補です。安全性を高めるためです、一般性、使いやすさは現実のプロジェクトにとって非常に重要です。ただし、仮想破壊、デフォルトのコピー構築の爆発的な性質、実行時のオーバーヘッド、constの正確さなどについても忘れないでください。

5
Coder