Cプログラマは何を知っているべきですか?[閉まっている]


11

すべてのまともなCプログラマーが知っておくべき/知っておくべき概念/技術/言語機能は何ですか(一般的なソフトウェアエンジニアリングなどを除き、C固有のもののみに焦点を合わせます)。私のC知識の可能性のあるギャップを埋めることができるように知りたいです。


9
Stack OverflowのCの質問から始めて、不明な点がないか確認してください。
chrisaycock

3
ACプログラマーはおそらくそれを知っているはずです2 + 2 = 4
エドワードストレンジ

21
彼らは防弾靴を販売する店を知っている必要があります。
アダムクロスランド

1
このテーマについて書かれた本は数百冊あります。あなたの質問は本当にあいまいです。単なるリストではなく、適切な回答を得るには、より具体的にする必要があります。そして、この質問からこれまでのところ答えが大きくなっているのを見て、私はそれを作り直すか閉じる必要があると思います。
ウォルター

2
別のプログラミング言語?
ムハンマドアルカウリ

回答:


19

Cに固有ですか?ほとんどの手続き型言語に共通する標準的な構成要素は別として、次のように言わなければなりません。

  • (ab)プリプロセッサの使用
  • リンカとコンパイラ
  • ポインターポインターポインター!
  • 配列がポインターである方法は配列です
  • C文字列の仕組みと、それらがポインターおよび配列でもある方法
  • C文字列の不適切な使用がバッファオーバーフローを引き起こす可能性がある方法
  • 何かを何かにキャストする方法(結局はすべて1と0だけです:))
  • 手動メモリ管理malloc / free
  • スタックとヒープ
  • ポインターのエイリアシング(C99で不正な理由)
  • 厳密にクラスではなく、公開された一連の関数を使用したモジュール(.h / .cファイル)の観点から開発を考える
  • 組合
  • sprintfが足を吹き飛ばすことができる理由
  • 関数ポインター

リストに「バッファオーバーフロー」を追加します。
エイダンカリー

@エイダン、良いキャッチ。追加。
ダグT.

2
Cの配列とポインターが同じではない方法:books.google.ca/…–
Matthieu

ポインタは、少なくとも3回以上繰り返されている必要があります
のGaurav

8

ポインターを理解すると、コンピューターが理解できます。


12
いや、コンピューターを理解しているように錯覚するだけです。
ジョブ

4

pythagrasの優れた答えに加えて、

以下のような複雑な宣言の書き方(または少なくとも読む方法) char (*(*funcs[4])())[10]

funcsは、charのarray [10]へのポインターを返す関数へのポインターのarray [4]です。


1
それがとても複雑になったら、おそらくこれはコメントに属しますか?
ジョブ

7
多分彼はそのような書き方を避ける方法を学ぶべきでしょうか?
-FabianB

3
  1. 整数プロモーションルール
  2. すべてを既知の値に初期化します
  3. GOTOは、例外/障害の処理に使用する場合は特に悪ではありません
  4. mallocおよび/またはcallocはNULLを返すことがあります...チェックの戻り値を確認してください
  5. 頻繁に小さなメモリを割り当てると、ヒープの断片化が発生する可能性があります。
  6. ポインター演算
  7. ビットマスクはあなたの友達です
  8. x >> 1は、符号なし整数のx / 2と同等です

GOTOが邪悪ではない場合の+1 :)
zvrba

2

ACプログラマーは他の言語を知っているべきです!;-) OOP、関数型プログラミングなどのさまざまなパラダイムの他の言語の概念を知ることは、常に実り多いものです。

もっと真剣に言えば、難読化されたプログラミングコンテストを見るのは楽しく、不思議なことに、良い経験でもあります。


2

Pythagrasの答えへのコメントで「バッファオーバーフロー」について言及しましたが、おそらく私が少し意図したことを明確にする必要があります。Cでは、メモリを直接操作することは危険であることを知るだけでは十分ではありません。それが危険である正確な方法も理解する必要があります。私はこれらのすべてのケースで「自分自身を撃つ」という比phorが本当に好きではありません-多くの場合、それはあなたが引き金引いているわけではありませが、多くの場合あなたやあなたのユーザーに反する関心を持つ俳優です。

たとえば、降順のスタックを持つアーキテクチャ(最も一般的なアーキテクチャはこの法案に適合します-x86とARMが一般的に含まれます)で、関数を呼び出すと、関数の戻りアドレスは、ローカル変数で定義されたにスタック配置されます関数の本体。したがって、バッファをローカル変数として宣言し、次のようにバッファオーバーフローをチェックせずにその変数を外部に公開する場合:

void myFn(void) {
    char buf[256];
    gets(buf);
}

外部ユーザーは、スタックからのリターンアドレスを上書きする文字列を送信できます。基本的に、現在の関数につながるコールグラフのプログラムの実行時のアイデアを変更できます。したがって、ユーザーは、アーキテクチャの実行可能コードのバイナリ表現である文字列、スタックからオーバーフローするのに十分なパディングmyFn、およびmyFnあなたが与えたコードを指すためにリターンアドレスを上書きする追加データを提供します。これが発生した場合、myFn通常はその呼び出し元に制御を返すはずだったときに、代わりに悪意のあるユーザーが提供したコードに分岐します。信頼できないユーザーに公開される可能性のあるC(またはC ++)コードを記述する場合、この攻撃ベクトルを理解する必要があります。。スタックに対するバッファオーバーフローが、ヒープに対するバッファオーバーフローよりも頻繁に(常にではないが)容易に悪用される理由を理解する必要があります。malloc()ed領域に制御構造があるという考えは、プログラムが別のmalloc()、またはでクラッシュする理由を理解するのに役立ちますfree()

Cは、マシンがどのように動作するかについての低レベルの詳細を公開し、現在広く使用されている他のユーザー編集言語よりもマシンをより直接制御できます。大きな力には大きな責任が伴います。Cを安全かつ効果的に使用するには、実際にこれらの低レベルの詳細を理解する必要があります。


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