えっと、会社から支給されたC言語の本が、ANSI-C以前のC(いわゆる K & R C というやつかな?)で書かれているようなので、そのあたりの違いを少しだけ書いておきます。重箱の隅を突っつくようで嫌らしいのですが、私の性格なんで勘弁してください(できるか!)。
ANSI-Cで一番変わったのが関数周りでしょう。まずは宣言方法から見ていきます。
ANSI-C の関数の宣言は基本的に以下の通りです。
記憶クラス 型名 関数名(引数の型と名前) { 宣言と文 }これは基本的にC++にも受け継がれており、たとえば main 関数であれば
int main(int argc, char *argv[]) { .... }と書きます。
int main(argc, argv) int argc; char *argv[]; { ... }ただしこの書き方は現在はまず使われないもので、新いコンパイラだと「宣言方法が古いものです」などという warrning を吐いてくるものさえあります。現在のCやC++では一応はどちらの方式も通りますが、ANSI-Cに準拠させて書くべきでしょう。
ANSI-Cで一番変わったのはプロトタイプ宣言の出現によるプログラムスタイルでしょう。
プロトタイプとは関数の記憶クラス、戻り値の型、引数の型を事前に宣言するものです。Cコンパイラはソースの上部から順に処理していきますので関数呼び出しを前方参照(関数が呼び出している場所より後で宣言されている)で行うと、関数の型を呼び出し側の型と同じであるとみなして処理してしまいます。たとえば次のような例で問題が起きます。
01: #include02: 03: main() 04: { 05: printf("%lf\n", func(10)); 06: 07: return 0; 08: } 09: 10: double func(double a) 11: { 12: return a * 2; 13: }
01: #include02: 03: double func(double a); /* プロトタイプ宣言 */ 04: 05: int main() 06: { 07: printf("%lf\n", func(10)); 08: 09: return 0; 10: } 11: 12: double func(double a) 13: { 14: return a * 2; 15: }
その外にも変わった部分を簡単に紹介します。
enum型と、void型が追加になりました。特にvoidは重要で、返り値の無い関数やを明示的に宣言できるようになりました。そのため最近のコンパイラでは void 宣言していない関数が返り値を返さないとウォーニングやエラーとなります。また void 型のポインタが作れるようになったことも重要でしょう。
K & R 時代にはあいまいだった標準ライブラリやヘッダファイルが規格化されました。
新しいプリプロセッサ命令として#elif、defined、#erroe、#pragamが追加されました。また、文字列引用の #、トークン連結の ##が利用可能となりました。
double と同義語であった long float が廃止となり、double 以上の精度を持つ long double が追加されました。
隣接する文字列が結合されるようになりました。
char *buf = "Hello\nWorld\n";と書いていたものが
char *buf = "Hello\n" "World\n";とかけるようになりました。
構造体が直接代入できるようになり、同時に関数への受け渡しも可能となりました。
文字セットの少ない環境のために三連文字が追加されました。
定数の型を明確なものにするために、U、L、F、などの末尾子が追加になりました。
signed、const、volatileが追加となりました。
以前は floatはdoubleに変換されてから計算されていましたが、直接計算されるようになりました。そのため必要とする精度が少ないない場合は float を使った方が高速になりました。
8文字までしか有効でなかった識別子が31文字までに拡張されました。
'\a'などのエスケープ文字が追加となりました。
共用体の初期化
自動変数の構造体、共用体、配列の初期化
自動変数(auto型)の構造体、共用体、配列の初期化が可能となりました。
プロトタイプ宣言の話がでたのでヘッダファイルの作り方等を少々書いてみます。まずモジュール化する場合、モジュール毎にヘッダファイルを作成するのが一般的では無いでしょうか(C++ではほぼ必須ですが)。小さ目のプログラムだとヘッダ部分は一つのファイルにまとめてしまうこともありますが、大きめなものとなると分離したくなります。理由は簡単でモジュールの独立性を高めたいからです。ヘッダをまとめると言うことは他のモジュールと内容が混ざってしまうと言うことでありいい方法ではありません。独立させるということはそこだけ抜き出せるわけですから、独立にテストを行うなどもできますし、メンテナンス性の向上や再利用の可能性もでてきます。
ではヘッダにはどのような事を書けばいいのでしょう。それはモジュールのインターフェースすべてです。「ヘッダだけを見ればそのモジュールの本体を見る必要が無い」というのが理想です。即ち外部から呼ばれるべき関数のプロトタイプ宣言と外部から参照する可能性のあるグローバル変数の extern 宣言です。サンプルとしてはC++の世界のところでスタックの例を挙げているので参照して見てください。そしてできることならヘッダにはしっかりとコメントを入れて下さい。C言語では「プロトタイプ宣言=プログラムの仕様書」的な要素がふんだんにありますからコメントをしっかりと書いておけば大変役に立ちます。