プログラミングコンテストやコンテストでC ++が優勢なのはなぜですか?[閉まっている]


23

C ++は非常に高速な言語であることを理解していますが、Cはそれほど高速ではないのでしょうか、それとも場合によっては高速ではありませんか?

そうすれば、C ++にはOOPがあると言うかもしれませんが、ほとんどのプログラミングパズルに必要なOOPの量はそれほど大きくなく、私の意見ではCがそれを処理できるでしょう。

私がこれを求めている理由は次のとおりです。私はプログラミングのコンテストやコンテストに非常に興味があり、それらをCでコーディングすることに慣れています。ただし、大多数の人がC ++を使用していることに気付きました(たとえば、Google Code Jam 2011のファイナリスト25人中17人がC ++を使用していましたが、誰もCを使用していませんでした)。

オブジェクト指向とは別に、何がC ++をプログラミング競技に適した言語にしているのですか?大会でより良い成績を収めるために学んで使用すべき言語の特徴は何ですか?

背景については、私は自分がCにかなり習熟していると考えていますが、C ++を学び始めたばかりです。

回答:


56

そもそも、ある言語では他の言語よりもうまく解決できる問題が常にいくつかあります。「より良い」の定義により、特定の問題を他の言語よりも「より良い」解決する言語が常に存在します。ただし、非常に多くの問題には、非常に類似したニーズ(一部のI / O、一部の計算)があり、同様の要件(合理的な信頼性、合理的なパフォーマンス)に直面しています。

Cを既に知っているように、世の中の大部分の問題について、C ++には重大な欠点はなく、多くの重要な改善点があります。大胆な?そう考える人もいますが、実際はそうです。まず、非常に一般的なC ++の誤解をいくつか明確にすることから始めましょう。

  • C ++はCより遅いです。 間違っています!多くのCプログラムも有効なC ++プログラムです。また、このようなCプログラムは、CコンパイラまたはC ++コンパイラのいずれかでコンパイルした場合、同じ速度で実行する必要があります。

  • C ++固有の機能にはオーバーヘッドが必要です。違う!特定のC ++固有の機能(仮想関数呼び出しや例外など)によって導入されるいわゆるオーバーヘッドは、Cで同様の機能を実装した場合に導入するオーバーヘッドに匹敵します。

  • C ++はオブジェクト指向です。違う!C ++言語には、オブジェクト指向プログラミングと汎用プログラミングを容易にするいくつかの言語拡張が含まれています。C ++はオブジェクト指向の設計をどこにも強制しません-単にそれを許可します。Cでは、オブジェクト指向プログラミングも可能です。C++では、よりシンプルでエラーが発生しにくくなっています。

ですから、あなたが私を信じているなら、「C ++はCよりもそれほど悪くない」ということを証明しました。C ++をより良いCにしたものを見てみましょう。

  • より強力な型付け C ++の型システムはCよりも強力です。これにより、多くの一般的なプログラミングエラーが防止されます。

  • パラメータ化された型 templateキーワードを使用すると、プログラマはアルゴリズムの一般的な(型に依存しない)実装を記述できます。Cでは、次のような要素を使用して一般的なリストの実装を記述できます。

    struct element_t {
      struct element_t *next, *prev;
      void *element;
     };

C ++では、次のような記述が可能です。

template <typename T>
struct element_t {
   element_t<T> *next, *prev;
   T element;
};

C ++実装は、一般的なプログラマーのエラー(リストに間違った型の要素を置くなど)を防ぐだけでなく、コンパイラーによる最適化も改善します!たとえば、一般的な並べ替えの実装はCとC ++の両方で利用可能です-

Cルーチンは次のように定義されます。

void qsort(void *base, size_t nmemb, size_t size,
           int(*compar)(const void *, const void *));

一方、C ++ルーチンは次のように定義されます

template void sort(RandomAccessIterator first, RandomAccessIterator last);

違いは、たとえば、整数の配列を並べ替える場合、Cの場合、すべての単一比較に対して関数呼び出しが必要になるのに対し、C ++実装では、実際の並べ替えルーチンとして、コンパイラーが整数比較呼び出しをインライン化できることです。コンパイラーによってコンパイル時に自動的にインスタンス化され、テンプレート引数に正しいタイプが挿入されます。

  • より大きな標準ライブラリ C ++では、C標準ライブラリを完全に使用できます。C標準ライブラリは実際のプログラムを作成する際に非常に貴重なリソースであるため、これはもちろん非常に重要です。ただし、C ++には標準テンプレートライブラリが含まれています。STLには、上記のソートルーチンのような便利なテンプレートが多数含まれています。リスト、マップ、セットなどの便利な一般的なデータ構造が含まれます。ソートルーチンと同様に、他のSTLルーチンとデータ構造は、プログラマの特定のニーズに合わせて「調整」されています。タイプ。

もちろん、STLは特効薬ではありませんが、一般的な問題を解決する際に非常に頻繁に役立ちます。Cでリストを実装した頻度はどれくらいですか?RBツリーは、あなただけがそれをする時間を持っていた場合、どれくらいの頻度でより良いソリューションになりましたか?STLを使用すると、このような妥協をする必要はありません。より適切な場合はツリーを使用し、リストを使用するのと同じくらい簡単です。

わかりましたので、私は良い部分だけを議論してきました。欠点はありますか?もちろんあります。ただし、その数は日々減少しています。説明させてください:

  • 良いC ++コンパイラはありません。長い間、このようなものでした。しかし、言語は1998年に標準化されたことを覚えておく必要があります。Cよりも複雑な複雑な言語です。コンパイラが標準に追いつくのに長い時間がかかりました。しかし、この記事の執筆時点では、最も広く使用されているプラ​​ットフォーム向けの優れたコンパイラが利用可能です。バージョン3.XのGCCは一般に非常に優れており、GNU / LinuxおよびほとんどのUNIXプラットフォームで実行されます。IntelにはWin32用の優れたコンパイラーがあります-これもかなり優れていますが、残念ながら、まだ標準以下のMS STLに依存しています。

  • 人々は良いC ++を知らないこれはよく聞かれる不満ではありませんが、私はよく見ます。C ++は大きくて複雑な言語ですが、特に「OOPが飢solveを解決し、エイズやガンを治す」時代に大いに宣伝された言語でもありました。その結果、多くの本当に貧弱なC ++コード、基本的にはあちこちにクラス宣言がいくつかある悪いCが出回っており、学習教材として使用されているようです。これは、C ++が実際にくだらないコードを実際に書いていることを知っていると信じている多くの人々を意味します。それはあまりにも悪いことであり、問​​題でもありますが、これをC ++のせいにするのは不公平だと思います。

したがって、C ++の2つの大きな問題は、C ++が若い言語であることの結果です。やがてそれらは消滅します。そして、世の中のほとんどの問題について、優れたプログラマーを獲得できる(または優れたC ++を自分で習得する)場合、その問題は今日の問題ではありません。


8
+1。非常に完全な答え。私が異なる意見を持っているのは、将来、C ++の主な欠点がなくなるということだけです。C ++には後方互換性が必要であるため、C ++から言語機能が削除されることはほとんどなく、新しい機能のみが追加されます(C ++ 11がこの完璧な例です)。これにより、言語は今日よりもさらに複雑になり、私見はC ++の最大の欠点です。
Doc Brown

@DocBrown:C ++の使用方法によって異なります。多数の古いコードを使用している場合は、それがどのように機能するかを理解する必要があります。したがって、おそらくC ++の幅広い知識が必要です。競争などで新しいコードを作成しているだけであれば、使用するものだけに限定することができ、多くの手間を省くことができます(例:などauto_ptr<>)。
デヴィッドソーンリー

すばらしい答えですが、「多くのCプログラムは有効なC ++プログラムでもあります」とは違いがコード生成を変更しないため、十分に強力ではないと思います。ほぼすべてのCプログラムは、比較的少ない労力で同じパフォーマンスの有効なC ++プログラムとして書き直すことができます。
ロボット

3

そのようなコンテストは、プログラマーの速度ほどプログラムの速度に関するものではありません。C ++には、標準ライブラリ機能、タイプセーフ、メモリ管理のヘルプがあり、実行可能ファイルがやや遅くなる場合でも、開発とデバッグを高速化します。


2

以前のCode Jamファイナリストとして言えば、それは主に言語機能ではなくライブラリに関するものです。競合ソリューションでは、OOP設計原則を使用することはほとんどありませんが、ほとんどの標準ライブラリコンテナーとアルゴリズムのツアーを見ることができます。 bitset、lower_bound、reverse、sort、find、count、nth_element、min、max、min_element、max_element、unique、next_permutation、... Cでデバッグします。

Code Jamでは、競技者が独自のコードを持ち込んでサードパーティライブラリを使用できるようにしているため、理論的には競技者はこれをすべてCで事前実装できます。ただし、すべてのコンテストでこれが許可されるわけではなく、 Cよりも

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