Cを学ぶ必要がありますか?


8

私はサイエンティフィックコンピューティングの博士課程の学生で、過去数か月間、PythonとC ++を正しい方法で学ぶのにかなりの時間を費やしました。私はC ++をよく学んだと感じています。良い参考書を手元に置いておけば、Pythonを使用して自分のやりたいことができるようになります。

また、MATLABを十分に理解しているため、自分のアイデアのプロトタイプを作成し、解決策を得ることができます。(もし私が最初の選択であるPythonをコーディングするのに飽きすぎている場合)。

CとC ++を1つの "C / C ++"にまとめる必要があることをここで何度か読んだことがあります。それらは異なる動機を持つ非常に異なる言語であり、私はその見解に完全に同意します。

私は常に学習しているのでC ++を "知っている"と主張することはできませんが、それをどのように使用すべきか、どのように使用すべきでないかはほとんど理解していると思います。私が学んだ最初の言語はCでしたが、最後に使用してから非常に長くなります。私の質問は本質的にこれです:

私がMATLAB、C ++、Pythonを知っていることを考えると、Cの学習に時間をかけるべきですか?上記の3つの言語についての知識は、コーディングするのに十分ですか?

私の研究は、数値線形代数の側面に関するものですが、離散イベントシミュレーション/確率論的プロセスのコンサルティングも行っています。私の意図は業界で働くことです(私の顧問は、C ++を学ぶことを勧めたので、彼には言語の個人的な好みはありませんが、雇用を続けることができます)。


Fortran 60とFortran 2003の違いは、C99とC ++ 98の違いよりも大きくなっています。そして77と2003年の間はほとんど同じです。それでも、人々はそれらを「ちょうど」Fortranと呼びます。
Misha

1
これらすべての他の言語を投げて、Fortranを学ぶだけです;)現代のFortranは、あなたが行うために必要なすべてを備えています。
ナセル

どちらの言語を使用する場合でも、維持する必要のあるコードを文書化し、いくつかの例と自動テストを含めてください。あなたがそれをしていないなら、あなたは本当にどんな言語も知りません。
cjordan1 2013

@Nasser(大規模なオープンソースフレームワークで作業する場合を除く)。Lammps、dealii、Trilinos、MercuryDPM、すべてC ++。Fortran以外のすべてを学ぶことをお勧めしますが、結局それは好みの問題です。
BlaB

回答:


13

CとC ++の比較のみを扱います。Cで記述されたものはすべて、いくつかの構文修正でC ++に移植できることは事実ですが、コミュニティーには異なる値があります。Cライブラリコミュニティは、他のどのライブラリよりも、バイナリの安定性を重視しています。バイナリの安定性は、特にバイナリ配布モデルと共有ライブラリで使用される場合に、低レベルのライブラリが上記のレイヤーに常に痛みを与えることを避けるために重要です。Cは、上記のレイヤーを再コンパイルせずに新しいリリースを出荷する機能を備えた、機能する必要のあるライブラリーの圧倒的な設定です。

このレベルで動作するC ++ライブラリを出荷することは可能ですが、結局「CをC ++で記述する」必要があります。たとえば、プライベートヘッダーまたは仮想メンバーを持つ構造体定義をパブリックヘッダーに配置したり、パブリックインターフェイスでテンプレートを使用したり、データメンバーを持つクラスからの継承に基づくAPIを使用したりすることはありません。これらの制約は、依存関係を正確に含めるために必要です。これにより、バイナリインターフェイスを変更せずに実装を変更できます。Cは、その単純なオブジェクトモデルと明確に定義されたABIにより、さまざまな言語からのバインドがはるかに容易になる傾向があります。

ライブラリレベルではなくアプリケーションレベルでコードを記述している場合、バイナリインターフェイスは重要ではないため、これらの懸念の多くは解消されます。継承やテンプレートなどのC ++言語機能を使用すると、依然として密に結合されたコードが生成される傾向があり、プロジェクトの成長に伴って、時間のかかる再コンパイルが発生します。より広範なコンパイル時の依存関係に加えて、CコードをC ++コンパイラで単純にコンパイルすると、コンパイル時間が大幅に増加します(ほとんどのツールチェーンで約2倍)。

これらに関心がある場合、または低レベルのライブラリで作業する予定がある場合は、Cに時間をかける価値があります。C ++言語機能の使用が好きで、バイナリインターフェースや結合の密性にそれほど煩わされていない場合は、時間の有効な使用方法ではない可能性があります。しかし、将来これらのことが気になるようであれば、Cに注意してください。


非常に多くの素晴らしい答えがあり、1つを選ぶのは困難でしたが、これは私の説明では最も説明的で完全なものでした。みんなに+1。たくさんの見方を堪能しました。私はC ++を完璧にしていき、必要に応じてCを学ぶことにしました。
インクエスト

完全を期すために、pimplイディオムを追加することをお勧めします。これは、C ++プログラマーが「コンパイルファイアウォール」を構築できるため、基盤となる実装の変更後にアプリケーションコードを再コンパイルする必要がありません。
cjordan1 2013

7

「Cを学ぶ」というよりは、プログラミング技術の向上とコンピューターサイエンスの幅広い知識の向上に重点を置く必要がある十分なプログラミングと十分なプログラミング言語での作業を終えた時点でいることをお勧めします。次に、特定のプロジェクトで必要な場合に、Cを学習します。

経験豊富なプログラマーは、特定のプロジェクトの必要に応じて、新しいプログラミング言語をすぐに習得します。言語から言語に変換する重要な概念を理解しているため、これを行うことができます。これらのより高いレベルの概念を習得していれば、構文はそれほど問題ではありません。生徒が2番目のプログラミング言語を学習しようとしているのを見ると、彼らが最初の言語の一部ではなかったいくつかの新しい概念を理解することに苦労しているのをよく目にするでしょう。たとえば、Fortranで始まる学生は、Cのポインターに苦労することがよくあります。Cを知っている学生は、C ++のオブジェクト指向機能に苦労することがよくあります。


6

この質問への答えは、本当にあなたが本当に何をするかに依存します。

高性能コンピューティングを行うコンピュータサイエンティストとして、Cでのプログラミングを理解/理解することは不可欠だと思います。

あなただけやっている場合でも、ものをコンピュータ上で、その後、C ++の知識はあなたを介して取得するのに十分でなければなりません。

より具体的には、計算の側面、つまり現代のコンピュータを最大限に活用するアルゴリズムの記述に本当に興味がある場合、メモリ管理、データレイアウト、SIMDなどの低レベルの側面に対処する必要を回避することはできません。ベクトル化、命令レベルの並列処理、共有メモリの並列処理、またはGPUコンピューティング(CUDAおよびOpenCLはCに基づいています)。

現在、これらのほとんどは、コンパイラー(メモリー管理、データレイアウト、ベクトル化など)や高レベルの抽象化(OpenMP、OpenACC、最適化されたライブラリーなど)で処理できます。しかし、ある程度は。手で物事を行うと、通常はより多くの作業が必要になりますが、見返りはパフォーマンスの桁違いになることがあります。

基本的に、自分詳細制御したいときはいつでも、「金属に近い」ため、通常はCを使用することになります。問題は、しかし、あなたが本当に望んでいるものなのかということです。


1
C ++はCよりも金属から離れていると言えますか?Cでできること、Cでできないこと そして、低レベルの計算のためのC ++にはごくわずかな有用な機能があると言っていますか?
Milind R 2013

@MilindR:確かに、CプログラムをC ++コンパイラでコンパイルできるため、C ++はCが行うすべてのことを実行できます。問題は、C ++が提供する追加機能、たとえば、ポリモーフィックオブジェクト、テンプレート、パイプなどにあります。これらは、実際の「金属」にうまくマッピングできません。C ++のこれらの機能のいずれかを使用すると、命令ごとに、プログラムが実際に行っていることを制御できなくなります。それが私が作ろうとしていた点であり、私はそれに立っています。
ペドロ

多態性オブジェクトについては同意しますが、テンプレートを使用して金属から遠ざけるにはどうすればよいですか?ここでは継承階層について言及していると思います。それらを使用しないものは、金属に非常に近い可能性があります。
Milind R 2013

1
@MilindR:いいえ。floatまたはのベクトルのテンプレートクラスを使用するとしますdouble。これらのベクトルの実際の操作は、一方または他方に最適な方法で実装されますが、両方に最適化されることはありません。継承階層には、ポリモーフィックオブジェクトと同じ問題があります。コンパイル時に正確な型がわからない場合、正しい関数を選択するときにわずかなオーバーヘッドがかかるだけでなく、ターゲット関数をインライン化することもできません。
ペドロ

それがテンプレートの特殊化の目的です。コンパイル時に型がわからないためにオーバーヘッドが発生することに同意します。
Milind R 2013

4

この質問に対する私の回答から、いくつかの追加の詳細を含むコピーと貼り付けが少しあります。

私は、業界(調査および機械制御機器メーカー)で、弱い組み込みプロセッサ(携帯電話のプロセッサと考えます)を使用しています。この場合、計算量の約50%が数値計算に費やされます。

HPCグループで働いていた数学者が1人働いているため、これは最終的に仕事を見つけることができる奇妙な場所の1つです。

この環境では、ほぼ確実にオペレーティングシステム(Linux、QNX、WinCEなど)があり、C ++が主流です。Cは、カーネル作業(つまり、デバイスドライバー)と、オペレーティングシステムなしの深く埋め込まれた作業(8ビットマイクロ)にのみ使用します。数値計算にはCを使用しません。実際、私たちのプラットフォームにはFORTRANコンパイラーがありません!

処理には1ワットのCPUしかないため、高いパフォーマンスが重要になります。並列処理の「魅力的な」問題の一部はありませんが、キャッシュとメモリを認識する必要があり、SIMDを認識する必要が高まっています(NEONと考えてください)。さらに、HPCとは異なり、レイテンシ(これはマシン制御です)と、スケジューリングやコンテキストスイッチングなどのオペレーティングシステムのその他の側面を鋭敏に認識する必要があります。メモリの割り当ては、この環境で特に厄介です。これは、ほぼ確実にコンテキストの切り替えを意味するためです(==レイテンシ、および400MHz CPUでは、時間の点で高価です)。

これらの問題は言語の選択とは無関係であるため、Cが必要であるという@Pedroの回答に同意しません。結局のところ、C ++を使用する場合、SIMDのコンパイラ組み込み関数を使用できます。ただし、これは、使用するC ++の機能とそのコストに非常に注意する必要があることを意味します。

したがって、答えを完成させるために、いいえ、Cは必要ありません。分析作業にはMATLABを使用し、スクリプトにはpythonを使用するので、少なくとも私の業界では、C ++以外の2つの言語が適しています。


3

Cについて知っておくと便利です。実際にCの科学計算に関連するC ++のOO機能の多くを問題なく実装できます(PETSCのソースコードを見て、その機能を確認することは非常に有益です)それ)。

とはいえ、この質問に対する万能の答えはありません。言語の選択には多くの要素があり、ランタイムもその1つです。コードの記述、デバッグ、プロファイリングにどれだけの時間を費やすかは、もう1つの重要な要素です。最終的には、できるだけ生産性を高めたいと考えています。研究の高パフォーマンスの側面に入るつもりである場合、またはコードの実行に非常に長い時間がかかると予想される場合(つまり、ランタイムがコーディングワークフロー時間を上回る)、Cを知ることは素晴らしいことです。そうでなければ、C ++を知っていて、これらが問題ではない場合は、Cコードを十分に理解して、それを使用している人と通信できるはずです。


2
しかし、Cは本当にC ++よりも高速ですか?
インクエスト

2
プログラミング言語はアプリオリに速くも遅くもありません、その有効性を決定するのは良いコードを書くのはプログラマーです。Cの利点は、Cが非常にシンプルで、C ++やPythonで効率的なコードを書くよりもはるかに簡単なことです(ここでは、言語の能力をフルに活用していると想定しています)。独自のメモリ管理をローリングし、演算子のオーバーロードであらゆる種類の厄介なことを実行する必要があるフル機能を利用した非常に高速なC ++コードを見たことがあります。同じ速度で同等のCバージョンを作成するのにかかる時間と比較してください。
Reid.Atcheson、2013

2
@GeoffOxberryあなたが言及するパッケージのいくつかは、スピードよりもはるかに柔軟性(ある範囲内)のために実際に書かれています。絶対的な速度で書かれたものは、デバッグが困難で、コンパイル時間が非常に長く、テンプレートの使用に固有の大きなバイナリが、パフォーマンスに本当に必要なものをはるかに超えています。もちろん、C ++で "C"パッケージを書くこともできますが、コミュニティの値はかなり異なります。
Jed Brown

1
さらに、「高性能」とは、必ずしも高性能のコードを書くことを意味するものではありませんでした。HPCの調査面では、多くの下位レベルの詳細を扱うことが多かったのです。これらは、C ++スタイルのプログラミングを使用して隠すことができます。これは必ずしも悪いことではありませんが、それはあなたの目標が何であるかに依存します。
Reid.Atcheson 2013

1
言い換えると、あなたがHPC研究者である場合、たまたま高速である別のパッケージを使用してコードを書くことは、研究的にはそれほど価値がありません。人々はあなたのコードがなぜより速いのか、なぜあなたのアプローチが効果的であるのかを知りたがるでしょう。
Reid.Atcheson 2013

2

最近のようなcの値は、低レベルの抽象化(たとえばpythonと比較)でコンピューターの機能に慣れることを強制することです。現在、c ++はcのすべての低レベルの機能を備えており、同様に立つことができますが、ほとんどの人は、最低レベルの抽象化を避け、(十分にテストおよびデバッグされた)高レベルの抽象化に依存するように c ++を学習するときに奨励されます。コンテナーライブラリ、スマートポインター、ポリモーフィズムなど。

ほとんどのプログラマーは、高度な抽象化の領域で遊ぶことにほとんどの時間を費やすことは理にかなっています。なぜなら、達成する方法の細かい細部を処理するよりも、精神的な時間とエネルギーを費やすことができるからです。

そのような態度の代償として、最低限の期待であるときに抽象化されたリークが発生するリスクがありますがプログラミングの全体的な効率はほぼ確実に向上します。

したがって、コンピュータの低レベルの機能について知っていることに満足している場合は、cを安全にオフにできます。そうでない場合でも、c ++の制限されたセットを使用して同じことを実行できます。


1

Stack Overflowで同様の質問に一度答えました。明白な答えは、あなたができるすべてを学ぶことですよね?

それでは、否定的な視点を見てみましょう。あなたはすでに3つの言語に習熟しているので、科学的プログラミングに関してはCよりも価値があると思います。科学的なソフトウェアを作成するコンサルティング業務では、MATLAB、Python、FORTRAN、Javaを使用しました。CやC ++を使用する必要はありませんでしたが、私の仕事はすべて新しいプロジェクトで行われていることに注意してください。C / C ++で大規模なプロジェクトを開始するようにクライアントにアドバイスはしませんが、C / C ++を使用するやむを得ない理由がない限り、JavaまたはScalaを推奨します。小規模なプロジェクトでは、おそらくPythonを使用します。あなたの場合、必要に応じてCを処理できるように見えます。

私は、あなたが働くドメインについてもっと学ぶことは、言語の騎手である以上に報われることを期待しています。結局のところ、問題はツールではなく問題の解決策です。Knuthの「時期尚早の最適化」についての見解は、キャリアの準備にも当てはまります。


1

それはおそらくそれだけの価値はありません。

C ++とCは、計算科学において同じニッチを占める傾向があります(おそらく組み込みシステムは例外です)。以前はCコンパイラはC ++コンパイラよりも優れていた(機能が充実しており、最適化が優れていた)場合がありましたが、私が今理解している限りでは、そうではありません。

確かに、Cは素晴らしい言語です(私はC ++よりも好きです)。時間と欲求があれば、それを学ぶことをお勧めしますが、時間に縛られている場合は、「I Cで書かれているプロジェクトで作業する必要があります(それでも、C ++の知識の多くが引き継がれます)。


0

レガシーC / Fortranライブラリー(例えば、lapack)を新しいC ++プロジェクトにプルできるように、「extern C」リンケージで物事をコンパイルする方法について学ぶために、Cの知識は役に立つと思います。私はレガシーCライブラリの学習に多くの時間を費やしません。そのようなものは必要に応じてピックアップ/グーグルでき、C ++ stdlibの同等の機能で置き換えることもできます。

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