web-dev-qa-db-ja.com

Cは強く型付けされていますか?

引用するには Wikipedia

多くの種類の暗黙的な変換をサポートする2つの一般的に使用される言語はCとC++であり、これらは弱い型付けの言語であると時々主張されます。しかし、これらの言語は、異なるタイプのオペランドを混合する方法に十分な制限があるため、2つは厳密に型指定された言語と見なされるべきだと主張する人もいます。

より決定的な答えはありますか?

75
Sydius

「強く型付けされた」および「弱く型付けされた」は、広く合意された技術的意味を持たない用語です。明確に定義された意味を持つ用語は

  • 動的に型付けされたは、型が実行時に値に関連付けられ、異なる型の値を混在させようとすると「実行時型エラー」が発生する可能性があることを意味します。たとえば、Schemeで(+ 1 #t)と記述することでtrueに追加しようとすると、エラーが発生します。エラーが発生するのは、問題のコードを実行しようとした場合のみです。

  • Staticically typedは、コンパイル時に型がチェックされ、静的な型を持たないプログラムがコンパイラによって拒否されることを意味します。たとえば、MLで1 + trueを記述してtrueに追加しようとすると、プログラムは拒否され、(おそらく不可解な)エラーメッセージが表示されます。コードが実行されない場合でも、常にエラーが発生します。

柔軟性を重視する度合いや、実行時エラーを心配する度合いに応じて、異なるシステムを好む人がいます。

「強く型付けされた」は大まかに「静的に型付けされた」という意味で使用され、「弱い型付けされた」は「動的に型付けされた」という意味で誤って使用されます。 「強く型付けされた」という用語のより良い使用法は、「型システムを回避したり破壊したりできない」ことです。一方、「弱い型付け」は「型システムに抜け穴がある」ことを意味します。逆に、静的型システムを持つほとんどの言語には抜け穴がありますが、動的型システムを持つ多くの言語には抜け穴がありません。

これらの用語はいずれも、言語で利用可能な暗黙的な変換の数とは何の関係もありません。

プログラミング言語について正確に話したい場合は、「強く型付けされた」および「弱く型付けされた」という用語を避けるのが最善です。 Cは静的に型付けされた言語ですが、多くの抜け穴があります。抜け穴の1つは、任意のポインター型を他のポインター型に自由にキャストできることです。また、問題のタイプごとに1つずつ、2つのメンバーを持つCユニオンを宣言することにより、選択した2つのタイプの間に抜け穴を作成することもできます。

why-interpreted-langs-are-mostly-ducktyped-while-compiled-have-strong-typing で静的型と動的型について詳しく書いています。

141
Norman Ramsey

すべての言語を「弱い」または「強い」タイプに分類することは困難です-それはより連続的なものです。しかし、他の言語と比較して、Cはかなり強く型付けされています。すべてのオブジェクトにはコンパイル時の型があり、コンパイラーは、その型ではできないオブジェクトで何かをしている場合に(大声で)知らせます。たとえば、間違ったタイプのパラメーターで関数を呼び出したり、存在しないstruct/unionメンバーにアクセスしたりすることはできません。

しかし、いくつかの弱点があります。主な弱点の1つは型キャストです-基本的に、オブジェクトのタイプをいじくり回すと言われ、コンパイラーは(可能な場合は)静かでなければなりません。 void*は別の弱点でもあります。未知の型への一般的なポインターであり、それらを使用するときは、正しいことをしていることに特に注意する必要があります。コンパイラは、void*のほとんどの使用を静的にチェックできません。 void*は、キャストなしの任意の型へのポインターに変換することもできます(C++ではなくCのみ)。これは別の弱点です。

21
Adam Rosenfield

Cは、コンパイラエラーなしでキャストを介して任意の型を他の型に変換できるため、弱い型付けと見なされます。この問題の詳細については、こちらをご覧ください こちら

11
mipadi

これについての文献は明確ではありません。強く型付けすることはyes/noではなく、強い型付けの程度はさまざまだと思います。

プログラミング言語には、プログラムの実行方法の仕様があります。特定のプログラムで実行する方法が明確でない場合があります。たとえば、数値から文字列を減算しようとするプログラム。または、ゼロで除算するプログラム。これらの条件に対処する方法はいくつかあります。一部の言語には、これらのエラーを処理するためのルールがあります(たとえば、例外をスローします)。他の言語には、これらの状況に対処するルールがありません。通常、これらの言語には、不特定の動作を引き起こすプログラムのコンパイルを防ぐための型システムがあります。また、不特定の動作があり、コンパイル時にこれらのエラーを防止するための型システムを持たない言語もあります(不特定の動作にヒットするプログラムを作成すると、ミサイルが起動する場合があります)。

そう:

すべてのケースで実行時に行われることを指定する言語(文字列に数値を追加するなど)は、動的に型指定されたと呼ばれます。コンパイル時にエラーのあるプログラムの実行を妨げる言語は静的に入力されます。何が起こるかを指定せず、エラーを防ぐための型システムも持たない言語は、弱い型付けと呼ばれます。

Java staticly typed?はい、その型システムは数値から文字列を減算することを許可しないため。いいえ、ゼロで​​除算できるためです。コンパイル時にゼロによる除算を防ぐことができます。型システム:たとえば、ゼロにできない数値型(NonZeroIntなど)を作成し、この型を持つ数値のみで除算することを許可します。

Cは強く型付けされているのですか、それとも弱い型付けですか?型システムは一部の型エラーを許可しないため、Cは強く型付けされます。しかし、他のケースでは、何が起こるかが定義されていない場合は弱く型付けされます(そして型システムはあなたを保護しません)。

9
Jules

CはJavascriptよりも強く型付けされ、Adaよりも強く型付けされていません。

私はそれが連続体の強く型付けされた側面にもっと落ちると思います。しかし、他の誰かが同意しない可能性があります(たとえ間違っていても)。

決定的なのはどうですか?

7
Michael Burr

ここにたくさんの良い答えがあります。 Real World Haskell から重要なポイントを持ち出したい:

多くの言語コミュニティには、「強い型」の独自の定義があることに注意してください。それにもかかわらず、型システムの強さの概念について、簡潔かつ広義に語ります。

(をちょきちょきと切る)

型システムを囲む花火のルーツは普通の英語にあり、人々は「弱い」と「強い」という言葉に価値観を付けています。通常、強度は弱さよりも優れていると考えています。アカデミックな専門用語よりも多くのプログラマーが平易な英語を話します。また、アカデミックは、自分の好みに合わないどんなタイプのシステムでも実際に実を結びます。その結果、多くの場合、その人気のあるインターネット娯楽、炎の戦争です。

したがって、CとC++についての回答を見てください。ただし、「強い」と「弱い」は「良い」と「悪い」にマッピングされないことに注意してください。

4
slim

Cは静的に型付けされていると見なされます(変数をintからfloatに変更することはできません)。変数が宣言されると、そのようにスタックします。

ただし、型はフリップフロップできるため、弱い型指定と見なされます。

0とは何ですか? 「\ 0」、FALSE、0.0など。

多くの言語では、条件はブール式からブール値のみを取得するため、IF(変数)とは言えません。これらはより強く型付けされています。同じことが、文字と整数の間を移動する場合にも当てはまります。

基本的に、cには2つの主要な単純データ型、整数と浮動小数点数があります(ただし、精度はさまざまです)。他のすべてのブール値、列挙型(単純ではないが適合する)などは、それらの1つとして実装されます。文字も基本的に整数です。

文字列型、定義された値にのみ割り当てることができる列挙型、ブール値またはtrue/falseを生成する式のみを使用できるブール型がある他の言語と比較してください。

しかし、Perl Cと比較して強く型付けされていると主張できます。したがって、これらは有名な議論の1つです(vi対emacs、linux対windowsなど)。 C#はCよりも強い型付けです。基本的にどちらの方法でも議論できます。そして、あなたの答えはおそらく両方の方向に行くでしょう:)また、いくつかの教科書/ウェブページはCが弱く型付けされていると言い、いくつかはCが強く型付けされていると言います。ウィキペディアにアクセスすると、Cエントリには「部分的に弱い入力」と表示されます。 Python Cは弱い型付けです。したがって、Python/C#、C、Perlの連続体です。

4
Cervo

強く型付けされたという用語には、合意された定義はありません。したがって、「強い型付け」によってmeanを定義しない限り、質問に答えることはできません。

私の経験では、「強く型付けされた」および「弱い型付けされた」という用語はトロルによって使用されます排他的。フレームウォーを開始することを除いて、これらの用語はほとんど役に立たない。

厳密に型指定された言語の重要な側面は何ですか? StackOverflowをご覧ください。

2
Jörg W Mittag

デニス・リッチー(Cの作成者)およびブライアン・カーニガンによると、Cは強く型付けされた言語ではありません。次の行は本の一部ですCプログラミング言語 3ページ5段落

Cは強く型付けされた言語ではありませんが、進化するにつれてその型チェックが強化されています。

2
mightyWOZ

私の意見では、C/C++は強く型付けされています。型の変換を許可するハッキングのタイプ(void *)は、Cがマシンに近いために存在します。つまり、Pascalからアセンブラーコマンドを呼び出してポインターを操作することができ、Pascalは依然として強く型付けされた言語と見なされます。 JNIを介してJavaからアセンブラーおよびC実行可能ファイルを呼び出すことができますが、Java弱く型付けされません。

Cには、生のポインタなどでアセンブラが「埋め込まれ」ているだけです。

2
mannicken

「弱く型付けされた」と「強く型付けされた」の間に複数の平行した道がある連続体があります。

Cは静的型であり、コンパイラーは宣言済みすべてのローカル変数と構造体メンバーの型を知っています。

各オブジェクトが特定の型を持っているが、コンパイラがその型を知る方法がない場合、動的に型付けされた言語は依然として強く型付けされている可能性があります。

1
yfeldblum

cは弱く型付けされ、bは型なしです。

1
plan9assembler

私はあなたのコンパイラ/プラットフォームが指示するようにCが強く型付けされていると言うでしょう。たとえば、厳密なプラットフォーム上でビルドしている場合、型のパンされたポインターの逆参照は壊れる可能性があります。

void m_free(void **p)
{
        if (*p != NULL) {
                free(*p);
                *p = NULL;
        }
}

....
char *str = strdup("foo");
m_free((void **) &foo);

コンパイラーに厳密なエイリアスをスキップするように指示した場合、これは問題ではありませんが、移植性はあまりありません。したがって、その意味では、言語の限界を押し広げることは可能ですが、おそらく最良のアイデアではありません。これは、通常のキャストを超えたステップです。つまり、intをキャストすると、空虚の落とし穴の1つを実際に示します。

したがって、Cは基本的に厳密に型指定されていると思いますが、そのさまざまなコンパイラは、プログラマが最もよく知っていて、ある程度の柔軟性を許していると想定しています。これは本当にコンパイラに依存しており、その潜在的なおっとに気付かない人もいます。その意味で、質問に答える際には、選択したコンパイラーが実際に役割を果たします。多くの場合、正しいものは、コンパイラーで回避できるものとは異なります。

0
Tim Post

クエリの理由は何ですか?私が尋ねる理由は、これはちょっとした違いであり、「強く型付けされた」のあなたの特定の用法は多かれ少なかれ明確化を必要とするかもしれないからです。私は間違いなく、Javaと他の言語には暗黙的な型の会話に対するより厳しい制限があります。

0
BobbyShaftoe

「強く型付けされた」という具体的な定義がない場合、具体的な答えを提供することは困難です。 Cはすべての変数とすべての式に型があるという点で強く型付けされていますが、キャストを使用して型を変更し、ある型の表現を別の型として再解釈できるという点で弱い型付けです。

0
Robert Gamble