SICPを読み、Scheme、および抽象データ型の実用的なアイデアを学びます。その後、Cでのコーディングは簡単です(SICP、Cの少なさ、PHP、Rubyなどの少なさから...あなたの思考は十分に広がり、オブジェクト指向プログラミングはすべての場合、ただしある種のプログラムのみ)。おそらく最も難しい部分であるCの動的メモリ割り当てに注意してください。C99やC11は、言語標準をプログラミングし、そのC標準ライブラリは、実際には非常に貧弱である(それはTCPやディレクトリについて知らない!)、そしてあなたは、多くの場合、いくつかの外部ライブラリ必要がありますまたはインターフェイスを(たとえば、POSIX、libcurlの HTTPクライアントライブラリのため、libonion HTTPサーバライブラリーのための、GMPlib bignumsため、のようないくつかのライブラリlibunistring)...など、UTF-8のために。
あなたの「オブジェクト」はしばしばCに関連するstruct
-sであり、それらで動作する関数のセットを定義します。短い関数または非常に単純な関数については、他の場所で-d にするヘッダーファイルのstruct
ようstatic inline
に、関連するを使用して定義することを検討してください。foo.h
#include
オブジェクト指向プログラミングが唯一のプログラミングパラダイムではないことに注意してください。場合によっては、他のパラダイムの価値があります(OcamlやHaskellなどの関数型プログラミング、SchemeやCommmon Lisp、Prologなどのロジックプログラミングなど。宣言型人工知能に関するJ.Pitratのブログも読んでください)。Scottの著書「Programming Language Pragmatics」を参照してください
実際、CまたはOcamlのプログラマーは、通常、オブジェクト指向プログラミングスタイルでコーディングすることを望みません。役に立たないときにオブジェクトを考えるように強制する理由はありません。
いくつかstruct
とそれらを操作する関数を定義します(多くの場合、ポインターを介して)。あなたは、いくつかの必要がある可能性がタグ付けされた組合(多くの場合、struct
タグ部材と、多くの場合、いくつかのenum
、およびいくつかのunion
内部を)、あなたがあると便利かもしれません柔軟な配列メンバーをあなたのいくつかの末尾にstruct
-s。
いくつかの既存のソースコード内で見てフリーソフトウェアでC(参照githubの&sourceforgeの
いくつかを見つけるために)。おそらく、Linuxディストリビューションをインストールして使用すると便利です。ほとんどフリーソフトウェアのみで構成され、優れたフリーソフトウェアCコンパイラ(GCC、Clang / LLVM)および開発ツールを備えています。Linux向けに開発する場合は、Advanced Linux Programmingも参照してください。
例えば、すべての警告およびデバッグ情報を使用してコンパイルすることを忘れてはいけないgcc -Wall -Wextra -g
開発中&phases-をデバッグ-notablyし、いくつかのツールを使用することを学ぶ、例えばvalgrindのハントにメモリリーク、gdb
など、デバッガをするように注意してくださいされているものも理解未定義振る舞い、それを強く避けてください(プログラムがUBを持ち、時々「動作する」ように見えることを思い出してください)。
オブジェクト指向のコンストラクト(特に継承)が本当に必要な場合は、関連する構造体や関数へのポインターを使用できます。独自のvtable機構を使用し、各「オブジェクト」struct
を含む関数ポインターへのポインターで開始することができます。ポインター型を別のポインター型にキャストする機能を利用します(および、継承をエミュレートするためにstruct super_st
開始するフィールドタイプと同じフィールドタイプを含むからキャストできるという事実を利用しますstruct sub_st
)。Cは、いくつか以下で特定-inかなり洗練されたオブジェクトシステムを実装するのに十分であることに注意してください規則を通り、 - のGObject(GTK / Gnomeのから)を示しています。
本当にクロージャーが必要な場合、コールバックを使用してすべての関数に関数ポインターといくつかのクライアントデータの両方が渡されるという規則で、コールバックでエミュレートすることがよくあります(呼び出し時に関数ポインターによって消費されます)。また、(通常)独自のクロージャのような-s(関数ポインタと閉じた値を含む)を使用することもできます。struct
Cは非常に低レベルの言語であるため、独自の規則(他のCプログラムの実践に触発された)、特にメモリ管理、およびおそらくいくつかの命名規則を定義および文書化することが重要です。命令セットアーキテクチャについて何らかの考えを持つことは役に立ちます。ことを忘れてはいけないのCコンパイラはたくさんやることがあり最適化をあなたのコードに(あなたはそれを聞いている場合)、その(そのコンパイラに、手で休暇をマイクロ最適化を行うことについてはあまり気にしないリリースの最適化コンパイルソフトウェア)。ベンチマークと生のパフォーマンスに関心がある場合は、最適化を有効にする必要があります(プログラムがデバッグされたら)。gcc -Wall -O2
時にはメタプログラミングが役立つことを忘れないでください。多くの場合、Cで書かれた大きなソフトウェアには、他の場所で使用されるCコードを生成するためのスクリプトまたはアドホックプログラムが含まれています(また、X-マクロなどの汚いCプリプロセッサトリックを再生することもできます)。便利なCプログラムジェネレーターがいくつかあります(パーサーを生成するyaccまたはgnu bison、完全なハッシュ関数を生成するgperfなど)。一部のシステム(特にLinux&POSIX)では、実行時にgenerated-001.c
ファイルでCコードを生成し、実行時にコマンド(などgcc -O -Wall -shared -fPIC generated-001.c -o generated-001.so
)を実行して共有オブジェクトにコンパイルし、dlopenを使用してその共有オブジェクトを動的にロードすることさえできます&dlsymを使用して名前から関数ポインターを取得します。私はMELT(GCCコンパイラのカスタマイズを可能にするので、役に立つかもしれないLispのようなドメイン固有の言語)でそのようなトリックをしています。
点に注意してガベージコレクション(概念や技術参照カウントは、多くの場合、Cでメモリを管理するための技術であり、それはとうまく対処していないガベージコレクションの貧弱な形私見で循環参照 ;あなたが持っている可能性が弱いポインタをそのことについて、ヘルプを、しかし、それは難しいかもしれません)。場合によっては、Boehmの保守的なガベージコレクターの使用を検討することもできます。
qux = foo.bar(baz)
なりqux = Foo_bar(foo, baz)
ます。