C言語/中級者向けの話題
配列の文法についての制限

C言語では、Fortran や Perl のような配列同士の一括代入はできません。
配列の文法についての制限

のように、要素ごとに代入する必要があります。
配列の文法についての制限

は、一見すると配列に代入しているように見えますが、これは初期化の構文です。
配列の文法についての制限

また、
配列の文法についての制限

の sizeof a / sizeof *a は、「配列の要素数」を得る時のイディオムです。
main関数

プログラム起動時に呼び出される関数はmainと名付けられています。実装では,この関数のプロトタイプを宣言しない。この関数は,戻り値の型がintで,パラメータがない状態で定義されなければならない。
main関数

または2つのパラメータ(ここではargcとargvとしていますが、宣言された関数のローカルなものなので、どのような名前を使っても構いません)を持つものです。
main関数

またはそれと同等の方法で、またはその他の実装で定義された方法による。
main関数

コマンドラインから実行ファイル名などを入力してプログラムを実行する際、実行ファイルに文字列データを渡すことができます。
main関数

方法は、コンパイル後に、単にコマンド入力で、たとえば
main関数

のように、ファイル名の後ろに、渡したい文字列を書けばいい。(上記コマンドの場合なら文字列「moji」が渡される)
main関数

このように、実行ファイル自体に対して渡される情報を、プログラム仮引数と呼ぶ。(なお「プログラム仮引数」自体の意味は、単になんらかの関数の定義側で書かれた引数のことであり、実行ファイルとは関係ない。)
main関数

例えばコマンドプロンプトにおいて、
main関数

のようにプログラムを実行した場合、example.exeプログラムのmain関数に対して、「example.exe」、「ABC」、「DEF」、「GHI」という4個の文字列が渡される。
main関数

プログラム仮引数を利用するには、ソースコードのmain関数に
main関数

のようにmain関数に引数 int argc, char *argv[] をこの順番で書けばいい。
main関数

この順番を守ること。
main関数

第一引数の整数型の引数は、コマンドライン入力時の単語の数です。(実行ファイル名も単語1個ぶんとして数える。)
main関数

たとえばコマンド入力が
main関数

なら、argcは4になる。
main関数

上記の例の場合
main関数

コマンド入力は、ファイル名が example.exe なら、コンパイル後にたとえば
main関数

のように入力すれば、日本語で「こんにちは」と答える。
main関数

フリースタンディング環境でプログラムが利用できるライブラリ機能は、<float.h>, <iso646.h>, <limits.h>, <stdarg.h>,<stdbool.h>, <stddef.h>, <stdint.h> および <stdnoreturn.h>で、これ以外は実装で定義されます。
main関数

inline関数指定子は、関数の宣言だけで使用できます。 inline関数指定子は、その関数の呼び出しを可能な限り速くすることを示唆します。 この示唆が効果をもつ程度は、処理系定義とします。
main関数

inline関数は、その関数を呼び出した部分に展開して直接埋め込む。 関数呼び出しにかかる処理を短縮することができるが、コードを複数の部分に展開するためファイルサイズが大きくなる。
main関数

_Noreturn関数指定子は、関数が呼び出し元に戻らないことを示します。 _Noreturn関数指定子と<stdnoreturn.h>ヘッダファイルは、C11で追加されました。
main関数

_Noreturn関数指定子は、関数mainには適用できません。
main関数

関数へのポインタとは、ある関数のメモリアドレスを格納し、その関数に間接的にアクセスする方法です。 関数へのポインタは、次のような場合に使われる。 ひとつは、関数を呼び出す際に、関数へのポインタを引数として渡し、呼び出した関数の内部で、関数へのポインタが指す関数を実行する場合。 もうひとつは、関数へのポインタの配列をつくり、if文や、switch文で関数を呼び出すのをやめ、コードを単純にする場合。
main関数

関数へのポインタの宣言の記述は次のようになっている。
main関数

この宣言では、代入する関数と同じ返却値のデータ型と引数のリストを指定する必要がある。 また、演算子の優先順位のため、「*関数へのポインタ名」を囲う「()」を省略はできない。
main関数

関数のメモリアドレスを関数へのポインタに格納する記述は次のようになっている。
main関数

関数名の後ろに、「()」はいらないことに注意。
main関数

関数へのポインタを使って、間接的に関数を呼び出すには、次のように記述します。
main関数

再帰的呼出しとは、ある関数がその関数自身を呼び出すことです。 典型的な用途として、数学の階乗(5×4×3×2×1のような計算)などが、よくあげられる。
main関数

再帰的呼出しに向いた計算に再帰的呼出しを使うと、ソースコードを簡潔に書ける場合がある。
main関数

ただし、再帰的呼出しではハードウェア資源的には弱点があり、スタックを多く占有するので負担になるという弱点もある。 そのため、再帰的呼出しで桁数の多すぎる計算などをすると、与えられたスタック領域を使いはたてしまうと異常終了などのエラーを引きおこす場合もある。 これは、いわゆる「スタック・オーバーフロー」(stack overflow)というエラーの一種です。
main関数

この例では再帰的呼出しを使って、入力された整数の階乗を計算している。 3を入力した場合、処理の流れは以下のようになる。
main関数

6行目と11行目で print_binary 自身を呼び出し再帰呼び出しとなっています。 print_binary は、リエントラントでない関数 puts と putchar を呼び出しているのでリエントラントでは有りませんが、問題なく再帰呼び出しが行なえます。 このように、再帰可能性(Recursivity)と再入可能性(Reentrancy)は別個の概念で、再入可能性(Reentrancy)はマルチスレッドやシグナルハンドラーで問題になります。
構造体のビットフィールド

ビットフィールドとは、 1ビット以上のビットからなる、 構造体のメンバーの一種です。 ビットフィールドを用いると、 1ビット以上のビットに名前をつけ、 その名前でアクセスできます。
構造体のビットフィールド

ビットフィールドは、構造体を宣言する時メンバーとして次のように記述します。
構造体のビットフィールド

データ型は、(signed) intまたはunsigned intを指定します。 (signed) intを指定すると、上位ビットが符号として扱われる。 メンバー名とサイズとを「:(コロン)」で区切る。 サイズはそのメンバーを何ビットで表すかを指定します。
構造体のビットフィールド

上の例では、0か1かの値を持つ1ビットの8つのビットフィールドをもつbits構造体を宣言し各ビットフィールドに値を代入しその値を表示している。 なお、unsigned char型をビットフィールドに使えるかはコンパイラによる。
オブジェクト指向プログラミング

C言語は一般にオブジェクト指向プログラミング言語だとは考えられていませんが、従前の構造体やマクロを使うことでクラスの継承に類似した実装を行うことができます。
オブジェクト指向プログラミング

この例は、継承というより合成の例になっているという批判はありえます。