ウィキペディアを引用するには:
多くの種類の暗黙的な変換をサポートする一般的に使用される 2 つの言語は C と C++ であり、これらは弱い型付けの言語であると主張されることがあります。ただし、これらの言語は、異なる型のオペランドを混在させる方法に十分な制限を設けているため、2 つの言語を厳密に型指定された言語と見なすべきであると主張する人もいます。
もっと決定的な答えはありますか?
ウィキペディアを引用するには:
多くの種類の暗黙的な変換をサポートする一般的に使用される 2 つの言語は C と C++ であり、これらは弱い型付けの言語であると主張されることがあります。ただし、これらの言語は、異なる型のオペランドを混在させる方法に十分な制限を設けているため、2 つの言語を厳密に型指定された言語と見なすべきであると主張する人もいます。
もっと決定的な答えはありますか?
「強い型」と「弱い型」は、広く合意された技術的意味を持たない用語です。明確に定義された意味を持つ用語は次のとおりです。
動的型付けとは、実行時に型が値に付加されることを意味し、異なる型の値を混在させようとすると、「実行時型エラー」が発生する可能性があります。たとえば、Schemeで書き込みを行ってtrueに追加しようとする(+ 1 #t)
と、エラーが発生します。問題のあるコードを実行しようとした場合にのみ、エラーが発生します。
静的型とは、コンパイル時に型がチェックされ、静的型を持たないプログラムがコンパイラーによって拒否されることを意味します。たとえば、MLでを書き込ん1 + true
でtrueに追加しようとすると、プログラムは(おそらく不可解な)エラーメッセージで拒否されます。コードが実行されない場合でも、常にエラーが発生します。
柔軟性を重視する度合いと実行時エラーを心配する度合いに応じて、さまざまな人々がさまざまなシステムを好みます。
「強く型付けされた」は「静的に型付けされた」を意味するために大まかに使用され、「弱く型付けされた」は「動的に型付けされた」を意味するために誤って使用されることがあります。「強く型付けされた」という用語のより適切な使用法は、「型システムを回避または破壊できない」ということです。一方、「弱い型付け」は「型システムに抜け穴がある」ことを意味します。逆に、静的型システムを使用するほとんどの言語には抜け穴がありますが、動的型システムを使用する多くの言語には抜け穴がありません。
これらの用語はいずれも、言語で使用可能な暗黙の変換の数とはまったく関係がありません。
プログラミング言語について正確に話したい場合は、「強い型」や「弱い型」という用語は避けるのが最善です。Cは静的に型付けされている言語ですが、多くの抜け穴があります。1つの抜け穴は、任意のポインター型を他の任意のポインター型に自由にキャストできることです。また、問題のタイプごとに1つずつ、2つのメンバーを持つCユニオンを宣言することにより、選択した2つのタイプの間に抜け穴を作成することもできます。
静的型付けと動的型付けについては、why-interpreted-langs-are-mostly-ducktyped-while-compiled-have-strong-typingで詳しく説明しました。
すべての言語を「弱い」または「強い」型付けに分類するのは困難です。より連続体です。しかし、他の言語と比較して、C はかなり強く型付けされています。すべてのオブジェクトにはコンパイル時の型があり、その型ではできないことをオブジェクトで行っている場合、コンパイラは (大声で) 知らせてくれます。たとえば、間違ったタイプのパラメーターで関数を呼び出したり、存在しない構造体/共用体メンバーにアクセスしたりすることはできません。
しかし、いくつかの弱点があります。主要な弱点の 1 つは型キャストです。基本的には、オブジェクトの型をいじるつもりであり、コンパイラは (できる限り) 静かにする必要があると言っています。 void*
も別の弱点です。これは未知の型への一般的なポインターであり、それらを使用するときは、正しいことをしていることに特に注意する必要があります。コンパイラは、 のほとんどの使用を静的にチェックできませんvoid*
。 void*
キャストなしで任意の型へのポインターに変換することもできます (C のみで、C++ では不可)。これは別の弱点です。
C は、コンパイラ エラーなしでキャストを介して任意の型を他の任意の型に変換できるため、弱く型付けされていると見なされます。この問題の詳細については、こちらをご覧ください。
文献はこれについて明確ではありません。強い型付けはイエス/ノーではないと思います。強い型付けにはさまざまな程度があります。
プログラミング言語には、プログラムの実行方法に関する仕様があります。特定のプログラムで実行する方法が明確でない場合があります。たとえば、数値から文字列を減算しようとするプログラムです。またはゼロで除算するプログラム。これらの条件に対処するには、いくつかの方法があります。一部の言語には、これらのエラーを処理するための規則があります (たとえば、例外をスローします)。他の言語には、これらの状況に対処するための規則がありません。これらの言語には、通常、不特定の動作につながるプログラムのコンパイルを防ぐための型システムがあります。また、動作が規定されておらず、コンパイル時にこれらのエラーを防ぐための型システムを持たない言語も存在します (動作が規定されていないプログラムを作成すると、ミサイルが発射される可能性があります)。
そう:
すべての場合に実行時に何が起こるか (文字列に数値を追加するなど) を指定する言語は、動的型付けと呼ばれます。コンパイル時にエラーのあるプログラムの実行を防ぐ言語は、静的に型付けされます。何が起こるかを指定せず、エラーを防ぐための型システムも持たない言語は、弱い型付けと呼ばれます。
では、Java は静的に型付けされているのでしょうか。はい、その型システムでは、数値から文字列を減算することが許可されていないためです。いいえ、ゼロで割ることができるからです。型システムを使用すると、コンパイル時にゼロによる除算を防ぐことができます。たとえば、ゼロにすることができない数値型 (NonZeroInt など) を作成し、この型を持つ数値でのみ除算を許可します。
では、C は強く型付けされていますか、それとも弱く型付けされていますか? 型システムでは一部の型エラーが許可されていないため、C は厳密に型指定されています。しかし、何が起こるかが定義されていない他のケースでは、弱く型付けされています (そして、型システムはあなたを保護しません)。
C は Javascript より強く型付けされており、Ada より強く型付けされていません。
連続体の強く型付けされた側にもっと当てはまると思います。しかし、他の誰かが反対するかもしれません (たとえ彼らが間違っていたとしても)。
決定的なのはどうですか?
C は静的に型指定されていると見なされます (変数を int から float に変更することはできません)。変数が宣言されると、そのままスタックします。
ただし、型がフリップフロップされる可能性があるため、弱く型付けされていると見なされます。
0とは?'\0'、FALSE、0.0 など。
多くの言語では、条件はブール式からブール値のみを取得するため、IF (変数) とは言えません。これらはより強く型付けされています。同じことが、文字と整数の間の移動にも当てはまります。
基本的に、c には 2 つの主な単純なデータ型、整数と浮動小数点数があります (精度はさまざまですが)。他のすべてのブール値、列挙型 (単純ではありませんが適合します) などは、それらの 1 つとして実装されます。文字も基本的に整数です。
文字列型、定義された値にのみ割り当てることができる列挙型、ブール値または true/false を生成する式のみを使用できるブール型がある他の言語と比較してください。
しかし、Perl C と比較すると、強く型付けされていると主張できます。したがって、これは有名な議論の 1 つです (vi と emacs、linux と windows など)。C# は C よりも強力な型付けです。基本的には、どちらの方法でも議論できます。そして、あなたの答えはおそらく両方の方法になります:) また、一部の教科書/Webページでは、Cは弱い型付けであると書かれており、Cは強く型付けされていると書かれているものもあります。ウィキペディアに行くと、C のエントリに「部分的に弱いタイピング」と書かれています。Python C と比較すると、型付けが弱いと言えます。つまり、連続体の Python/C#、C、Perl です。
ここにはたくさんの良い答えがあります。Real World Haskellから重要な点を取り上げたいと思います。
多くの言語コミュニティが独自の「強い型」の定義を持っていることに注意してください。とはいえ、型システムにおける強度の概念については、簡潔かつ大まかに説明します。
(をちょきちょきと切る)
型システムをめぐる花火は、人々が「弱い」と「強い」という言葉に価値観を与える普通の英語にルーツを持っています。私たちは通常、強さは弱さよりも優れていると考えています。多くのプログラマーは学術用語よりも平易な英語を話し、多くの場合、学者は自分の好みに合わない型システムを実際に問題視しています。その結果、人気のあるインターネットの娯楽である炎上戦争が発生することがよくあります。
したがって、C と C++ に関する回答を見てください。ただし、「強い」と「弱い」は「良い」と「悪い」に対応しないことに注意してください。
私の意見では、C/C++ は強く型付けされています。型の変換 (void*) を可能にするタイプのハックが存在するのは、C がマシンに近いためです。つまり、Pascal からアセンブラー コマンドを呼び出してポインターを操作することができ、Pascal は依然として厳密に型指定された言語と見なされます。JNI を介して Java からアセンブラーと C の実行可能ファイルを呼び出すことはできますが、Java が弱く型付けされるわけではありません。
Cには、生のポインターなどを使用してアセンブラーが「埋め込まれている」だけです。
厳密に型指定されたという用語には、合意された定義がありません。したがって、「強く型付けされた」とはどういう意味かを定義しない限り、質問に答えることができません。
私の経験では、「強く型付けされた」および「弱く型付けされた」という用語は荒らしによって排他的に使用されます。なぜなら、それらの定義の欠如により、荒らしは議題に合わせて議論の途中でそれらを再定義できるからです。炎上戦争を開始する場合を除いて、これらの用語はほとんど役に立ちません。
また、強く型付けされた言語の重要な側面は何ですか?もご覧になることをお勧めします。ここStackOverflowにあります。
強く型付けされていません。
次の関数プロトタイプが引数のデータ型について何を示しているかを考えてみてください。
void func (int n, char ch, ...);
何もない。したがって、強い型付けはここでは適用しないことをお勧めします。
「弱く型付けされた」と「強く型付けされた」という、明確に定義されていない 2 つの用語の間には、複数の並行する道がある連続体があります。
C は、コンパイラがすべてのローカル変数と構造体メンバーの宣言された型が何であるかを知っているという点で、静的に型付けされています。
各オブジェクトに特定の型があるが、コンパイラがその型を知る方法がない場合、動的に型付けされた言語は依然として強く型付けされている可能性があります。
c は弱く型付けされ、b は型なしです。
「強く型付けされた」の具体的な定義がない場合、具体的な答えを提供することは困難です。C は、すべての変数とすべての式に型があるという点で強く型付けされていますが、キャストを使用して型を変更し、ある型の表現を別の型として再解釈できるという点で型付けが弱いと言えます。
お問い合わせの理由は何ですか?私が尋ねる理由は、これは一種の小さな違いであり、「強く型付けされた」の特定の使用法には多かれ少なかれ説明が必要な場合があるためです。Java やその他の言語では、暗黙的な型の会話に対する制限が厳しくなっていると断言できます。
Cは、コンパイラ/プラットフォームが指示するのと同じくらい強く型付けされていると言えます。たとえば、厳密なプラットフォームでビルドしている場合、タイプのしゃれのあるポインターを逆参照すると壊れる可能性があります。
void m_free(void **p)
{
if (*p != NULL) {
free(*p);
*p = NULL;
}
}
....
char *str = strdup("foo");
m_free((void **) &foo);
ここで、コンパイラに厳密なエイリアシングをスキップするように指示した場合、問題にはなりませんが、あまり移植性がありません。その意味で、言語の限界を押し広げることは可能ですが、おそらく最良のアイデアとは言えません。これは、典型的なキャスト、つまり int をできるだけ長くキャストするよりも一歩進んでおり、void の落とし穴の 1 つを実際に示しています。
したがって、C は基本的に厳密に型付けされていると言えますが、そのさまざまなコンパイラは、プログラマーが最もよく知っており、ある程度の柔軟性を許容していると想定しています。これはコンパイラに大きく依存します。その意味で、選択したコンパイラは、質問に答える際に実際に役割を果たします。何が正しいかは、多くの場合、コンパイラが許容するものとは異なります。
すべての式にはその値の関数ではない型があるため、それは強い型であると言えます。ei 実行前に知ることができます。
OTOH 強い型付けの正しい説明かどうかはわかりません。言語を作成する理由を理解できる唯一の強力な主張は、型キャスト、共用体の再解釈、他の言語の呼び出し、ポインター、アセンブリ言語などを介して、実行時に型システムを覆すことができないという保証です。このような言語存在しますが、非常に不自由であるため、高度な保証と学界以外のプログラマーにはあまり関心がないようです。誰かが指摘したように、本当にそれを正しく行うには、次のような型が必要になり始めますnonZeroInt
。うん。