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


19

学校では、クラスをはるかに凌いでいるという事実にもかかわらず、今年Cを学び始めました。クラスがCの基礎にある間にJava、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にも当てはまります。ファイルIOは、C ++よりもCの方がずっと簡単だといつも思っていたからです。この質問は、C ++に適用されるCのほぼすべての一般式に当てはまります。また、最新のコンパイラを使用していることも注目に値しますが、C ++コードでC式を使用するのが良いプログラミング習慣かどうかを尋ねているので、これは問題ではありません。

おそらくこれを行うことの短所と長所がありますが、私はyes / why、no / whyタイプの答えだけを探しています。

また、詳細があればコメントを投稿しません。


12
ミキシングstdioiostream。ファミリ内で保証される特定の順序と同期がありますが、必ずしも外部では適用されません。
デビッドソーンリー

先端をありがとう、しかしそのコードスクラップは純粋な例でした。とにかくありがとう。
バグスター

25
プログラミングを学習している場合; 適切なインデントを学ぶ必要
ビットマスク

5
scanf()は良い例ではありません。使用するのはひどくエラーが発生しやすいので、CまたはC ++では避けることをお勧めします。
ラッセルボロゴーブ

1
サンプルコードだけだったかもしれませんが、Davidのコメントは、C ++でプログラミングするときにCのイディオムを使用すべきでないという問題の核心になってます。これらは完全に異なる言語です。JavaとC、またはC ++とVisual Basicを混同するよりも、それらを混同しないでください。
コーディグレイ

回答:


36

いいえ、それは悪い習慣です。これを生計のために行うと、チームが固守するスタイルガイドに違反することになります(または、少なくともコードレビュー中に強打されます)。

はい、動作しますが、同等のC ++がある場合は、それを使用します。(例えばと混同printfsしないようにしてくださいcouts


+1-短く、ポイントまで。そして、これはチームのガイドラインが人々を結び付け、彼らが一緒に働くことができるように統一するのに役立つという私の答えの主要な点を強調しています。
jmort253

このコメントは私の質問にほぼ適切に答えており、確固たる議論をもたらしています。ありがとうございました。
バグスター

1
@ThePlanありがとう。誰もがこの質問に対して素晴らしい答えを持っていました。
-jglouie

1
注:printf一貫した使用は、一貫した使用と同様に機能しcoutます。唯一の問題は、それらを一緒に混合し、スタイルです。
user253751 14年

Cに相当するものがないCの機能の例を教えてください。
klutt

20

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

あなたは正しいです; ただし、そのCコードは問題なくコンパイルされます。それは、標準に従うという点であなたの会社がどれほど柔軟であるかにかかっています。インタビューで質問をされたことがあれば、CがC ++で動作することをインタビュアーに必ず知らせますが、CとC ++は2つの別個の言語であり、おそらく非常に、そうする正当な理由。

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

要約すると、何かをすることができるからといって、するべきではないというわけではありません。


そうですか。機能についてはどうですか、C構文がC ++構文よりも優れている特定のケースはありますか?
バグスター

10

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

ただし、コードを混ぜるのは悪い習慣だと思います。-useを使用scanfするprintf場合、-useをoperator >>使用する場合operator <<。オーバーロードされたC ++演算子が、知らない機能をカプセル化している可能性があり、それらの不一致により、プログラムが実行したくない機能を実行することになります。

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


5
CとC ++の非互換性は、単なるキーワードではありません。タイピングシステムが変更され、C ++には存在しないC(特にC99)に存在する機能があります。(たとえば、可変長配列)。
アラファンギオン

9

コーディングスタイルと見た目の問題を別にすれば、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プログラマーの補足:Visual C ++コンパイラには、Windows API CreateThread()関数がCライブラリと同じプログラムで使用された場合、かなり長い間リークバグがありました。(3、4)

  • 一部のコンパイラでは呼び出し規約が問題になる場合があり、extern "C"「C呼び出し規約」にリンクする必要がある関数を明示的に指定するために使用する必要があります。

  • 迷惑な詳細。コンマ演算子の動作は異なります。構造体/列挙型宣言の末尾のコンマはC99 / C11で許可されていますが、C ++では許可されていません。さまざまな種類の変数と関数のスコープは異なる方法で処理されます。などなど

さらに多くの場合があります。


参照:

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

7

C ++がCをコンパイルできる理由は、「後方互換性」のためだけです(既存の作業コードを書き換えないようにします)。

しかし、C ++にはcに関する異なる哲学があります。それらを混在させることは、両方に良いサービスを提供しません。

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

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


5

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

ただし、これらの2つの言語を混在させることは必ずしも必要ではありません。Cに共通する生のビット調整と相まって、C ++の非常識な複雑さを得るからです。

ご覧のように、あなたのような単純な例でも、さまざまなタイプのストリームと内部バッファリングとの同期の問題があります。しかし、C&C ++のアプローチは、決して柔軟ではありません。クラスxに切り替えます。ストリーミングなどを使用する演算子はありません。

それは複雑です...

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

しかし、C ++の少なくとも50%以上を習得するには、5年以上のプロのコーディングが必要です。20か月ほどの実地経験がある6か月のカリキュラムでは、それを管理することはできません。

CでC ++コンストラクトを使用する場合、ストリームは使用せず、鳥の目から見れば単純な方法であり、ソフトウェア開発は簡単であると人々に信じさせますが、多くの状況で多くの利点なしに余分な複雑さを隠します。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.