46

ANSI Cに関するウィキペディアの記事には、次のように書かれています。

ANSI C 標準化プロセスの目的の 1 つは、K&R C (最初に公開された標準) のスーパーセットを作成し、その後導入された非公式の機能の多くを組み込むことでした。ただし、標準化委員会は、関数プロトタイプ (C++ プログラミング言語から借用) や、より機能的なプリプロセッサなど、いくつかの新機能も含めました。パラメータ宣言の構文も、C++ スタイルを反映するように変更されました。

それは私に違いがあると私に思わせます。しかし、K&R C と ANSI C の比較は見当たりませんでした。そのようなドキュメントはありますか? そうでない場合、主な違いは何ですか?

編集: K&R の本の表紙には "ANSI C" と書かれていると思います。少なくとも、私が家に持っているバージョンはそうだと思います。もしかして、もう差がない?

4

11 に答える 11

32

ここで、「K&R C」とは何かについて混乱があるかもしれません。この用語は、「The C Programming Language」の初版に記載されている言語を指します。大雑把に言えば、1978 年頃の Bell Labs C コンパイラの入力言語です。

Kernighan と Ritchie は、ANSI 標準化プロセスに関与しました。「ANSI C」方言は「K&R C」に取って代わり、「The C Programming Language」のその後の版は ANSI 規則を採用しています。「K&R C」は「死んだ言語」ですが、一部のコンパイラがまだレガシー コードを受け入れている場合を除きます。

于 2008-08-22T14:48:18.003 に答える
18

関数プロトタイプはK&R CとC89の間の最も明白な変更でしたが、他にもたくさんありました。Cライブラリの標準化にも多くの重要な作業が行われました。標準Cライブラリは既存のプラクティスを体系化したものでしたが、複数の既存のプラクティスを体系化したため、より困難になりました。PJPlaugerの本であるTheStandardC Libraryは、優れた参考資料であり、ライブラリがそのようになってしまった理由の舞台裏の詳細についても説明しています。

ANSI / ISO規格Cは、ほとんどの点でK&RCと非常によく似ています。ほとんどの既存のCコードは、多くの変更を加えることなくANSIコンパイラ上に構築する必要があることが意図されていました。ただし、重要なのは、標準以前の時代には、言語のセマンティクスは各コンパイラベンダーによる解釈に開かれていました。ANSI Cは、すべてのコンパイラを同等の立場に置く言語セマンティクスの共通の記述をもたらしました。約20年後の今、これを当然のことと考えるのは簡単ですが、これは重要な成果でした。

ほとんどの場合、維持するための先行標準のCコードベースがない場合は、それについて心配する必要がないことをうれしく思います。もしそうするなら、あるいはもっと悪いことに、古いプログラムをより現代的な基準に引き上げようとしているなら、あなたは私の同情を持っています。

于 2008-08-28T03:15:27.200 に答える
12

多少の違いはありますが、K&R の後の版は ANSI C 用であると思いますので、実質的な違いはもうありません。
より適切な用語がないための「C Classic」には、関数の定義方法がわずかに異なっていました。

int f( p, q, r )  
int p, float q, double r;  
{  
    // Code goes here  
}

もう 1 つの違いは、関数のプロトタイプにあると思います。プロトタイプは、引数または型のリストを取る必要はありませんでした (実際、できませんでした)。ANSI C ではそうです。

于 2008-08-22T14:35:12.060 に答える
8
  1. 関数プロトタイプ。
  2. 定数および揮発性修飾子。
  3. ワイドキャラクターのサポートと国際化。
  4. 逆参照せずに関数ポインタを使用できるようにします。
于 2011-02-28T14:28:38.480 に答える
3

ANSI CとK&RCの主な違いは次のとおりです。

  • 関数プロトタイピング
  • constおよびvolatileデータ型修飾子のサポート
  • ワイド文字と国際化をサポート
  • 逆参照せずに関数ポインタを使用できるようにする

ANSI Cは、関数の定義と宣言に関数名、引数のデータ型、および戻り値のデータ型が含まれるc++関数プロトタイプ手法を採用しています。関数プロトタイプを使用すると、ANSI Cコンパイラは、無効な数の引数または互換性のない引数のデータ型を渡すユーザープログラムの関数呼び出しをチェックできます。これらは、K&RCコンパイラの主な弱点を修正します。

例:関数fooを宣言し、fooが2つの引数を取ることを要求する

 unsigned long foo (char* fmt, double data)
 {
      /*body of foo */
 }
于 2013-02-28T01:40:22.527 に答える
3

もう 1 つの違いは、関数の戻り値の型とパラメーターの型を定義する必要がないことです。それらは int であると想定されます。

f(x)
{
    return x + 1;
}

int f(x)
int x;
{
    return x + 1;
}

同一です。

于 2008-09-11T01:23:11.220 に答える
2

誰もまだ言及していない大きな違いは、ANSI 以前は、C は主に仕様ではなく先例によって定義されていたことです。特定の操作が一部のプラットフォームでは予測可能な結果を​​もたらし、他のプラットフォームではそうではない場合 (たとえば、関係のない 2 つのポインターで関係演算子を使用する場合)、先例はプログラマーがプラットフォームの保証を利用できるようにすることを強く支持しました。例えば:

  1. すべてのオブジェクトへのすべてのポインター間で自然なランキングを定義するプラットフォームでは、関係演算子を任意のポインターに適用すると、そのランキングが得られます。

  2. あるポインターが別のポインターよりも「大きい」かどうかをテストする自然な手段が、真または偽の値を生成する以外に副作用がないプラットフォームでは、任意のポインターへの関係演算子の適用も同様に、いかなる側面も持たないことに依存する可能性があります。 -真または偽の値を生成する以外の効果。

  3. 2 つ以上の整数型が同じサイズと表現を共有するプラットフォームでは、そのような整数型へのポインタを使用して、同じ表現を持つ他の型の情報を読み書きすることができます。

  4. 整数のオーバーフローが自然に暗黙のうちにラップされる 2 の補数プラットフォームでは、結果が INT_MAX+1u と UINT_MAX の間であり、それがは、より大きな型に昇格されておらず、 の左オペランド、、、または比較演算子 >>のいずれのオペランドとしても使用されていません。ちなみに、標準の理論的根拠は、小さな unsigned 型が signed に昇格する理由の 1 つとしてこれを示しています/%

C89 より前は、上記の仮定が自然に成り立たないプラットフォーム用のコンパイラが、いずれにせよそれらの仮定を支持することが期待されるかどうかは不明でしたが、そのような仮定を簡単かつ安価に支持できるプラットフォーム用のコンパイラは、ほとんど疑いの余地がありませんでした。そうすべきです。C89 標準の作成者は、次の理由から、わざわざそれを明示的に言いませんでした。

  1. ライターが意図的に鈍感にされていないコンパイラは、実用的な場合、言われることなくそのようなことを続けます (小さな符号なしの値を符号付きに昇格するための理論的根拠は、この見解を強く補強します)。

  2. 標準では、実装が 1 つのおそらく不自然なプログラムをスタック オーバーフローなしで実行できることのみを要求し、鈍感な実装は他のプログラムを未定義の動作を呼び出すものとして扱うことができますが、鈍感なコンパイラの作成者が書くことについて心配する価値はないと考えていました。 「適合」していたが役に立たなかった実装。

「C89」は同時に「C89 によって定義された言語に加えて、プラットフォームが提供する追加の機能と保証」を意味するものとして解釈されましたが、gcc の作成者は、C89 で義務付けられている機能と保証を超える機能と保証を除外する解釈を推し進めてきました。

于 2016-07-05T22:58:48.190 に答える
2

違いは次のとおりです。

  1. プロトタイプ
  2. ワイド文字のサポートと国際化
  3. const および volatile キーワードのサポート
  4. 関数ポインターを逆参照として使用できるようにする
于 2009-02-23T04:38:25.463 に答える
2
  • 関数のプロトタイピング: ANSI C は、関数の定義と宣言に関数名、引数 t、データ型、および戻り値のデータ型が含まれる C++ 関数プロトタイプ手法を採用しています。これらは、K&R C コンパイラの主な弱点を修正します。ユーザー プログラムでの無効な呼び出しは、多くの場合、コンパイルをパスしますが、実行時にプログラムがクラッシュする原因となります。
于 2011-06-04T15:46:19.137 に答える
1

最大の違いは、関数のプロトタイピングと、関数の引数の型を記述するための構文だと思います。

于 2008-08-22T14:31:19.120 に答える