キャストとはどういう意味ですか?


18

CIのような低レベル言語でコーディングする場合、キャストは「これらのバイトを常に他のタイプであるかのように再解釈する」こともあれば、「この値を他のタイプにインテリジェントに変換すること」を意味することもあります。

単語の本来の意味は何ですか?また、いつ変換を期待するか、いつ生の再解釈を期待するかについて一貫性はありますか?


あなたが理解できないウィキペディアの記事には何がありますか?「型変換型キャスト、および強制は、暗黙的または明示的に、あるデータ型のエンティティを別の型に変更する異なる方法です。各プログラミング言語には、型の変換方法に関する独自のルールがあります...」
gnat

「キャストする」という本来の意味は、プログラミングと共通点はありません。こちらを参照してくださいmerriam-webster.com/dictionary/cast-Doc
Brown

1
エリック
リッパートの

1
@gnat:それが深刻な質問なのか、単なるトローリングの試みなのかわかりません。しかし、コンパイラが何をするのかを知る方法を知りたいです:変換、キャスト、または強制?経験則は何ですか?
アレクサンダートーストリング14年

1
@DocBrown castコンピューティングの意味での用語は、冶金の意味での鋳造に似ていると思います。それにより、金型に注がれたときに溶融金属の形状が再形成されます:britannica.com/EBchecked/topic/377665/metallurgy/81884/Casting
KChaloux 14年

回答:


10

Cでのキャストは独特で、他の言語とはまったく異なります。また、決してインテリジェントではありません。

Cでのキャストは、慎重に定義されたルールを使用して、あるタイプから別のタイプに値を変換します。本当に知る必要がある場合は、標準を読んでください。それ以外の主なポイントは次のとおりです。

  1. 可能な場合、整数型間の変換では値が保持されます。宛先のビット数が多い場合、これは広くなり、一般に安全ですが、符号拡張が含まれる場合があります。狭い場合、ビットは失われます。
  2. ポインタータイプ間の変換ではポインター値が保持されますが、結果は未定義であることが多く、移植性がないことが多く、高度なシナリオに役立つことがよくあります。
  3. 整数型とポインター間の変換は、整数が十分に大きく、ビットパターンを保持していれば問題ありません(それが意味するものは何でも)。整数が小さすぎる場合、結果は未定義ですが有用ではありません。原則として、「long」は「void *」に対して十分な幅ですが、保証はありません!この方法で作成されたポインターは、あらゆる種類の興味深い方法で無効になる可能性があります。
  4. float型と整数型の間の変換は、適切なライブラリルーチンで定義された算術変換です(丸めではなく、切り捨てを使用)。
  5. 関数の戻り値をvoidにキャストできます。持ってない 何もしません。

一部のキャストは暗黙的に適用され、一部のキャストではコンパイラが警告を発行します。警告に注意するのが最善です!

役に立たないため、キャストの辞書定義は無視するのが最適です。多くのキャストは、変換または強制という用語でよりよく説明されているため、それらも知っておく価値があります。

C ++はもっと複雑ですが、そうではないのですか?


私は大まかな詳細ではなく、経験則に興味がありますが、物事を整理するのに役立つなら、C以外の言語にも興味があります。
アレクサンダートーストリング14年

2
ここで示したのは、合理的な範囲で汎用的なものです。本格的で低レベルのプロフェッショナルなC / C ++コードを作成するには、非常に細かい部分が重要です。ほとんどの言語では、型変換にこの種の問題はありません。問題が解決しない場合は申し訳ありません。
david.pfx 14年

相互変換は常に明確に定義されT*ていることを除きvoid*ます。
マイルルーティング

@Miles:実際には、T *を任意のU *に変換し、元のポインター値を保持するために戻す必要があります。私の答えでは、短くするために「しばしば未定義」とだけ言った、「細部のいくつかは非常に面倒です。
david.pfx

1
@supercat:n1570 S6.3.2.3を参照してください。T *、U *、およびvoid *間の変換/ラウンドトリップでは、常に1つの例外を除いてポインター値が保持されます。T *が正しく整列されていない場合、動作は未定義です。私はあなたの主張を受け入れますが、それだけです。
david.pfx

2

Webster辞書のこの部分は、適切な定義を提供します。

a:液体またはプラスチックを金型に流し込み、圧力をかけずに硬化させることで(物質)に形状を与える
b:このプロセスで形成する

したがって、キャストする前に、「オブジェクト」(文字通りOOPオブジェクトではない)は指定された形状(タイプ)にあります。あなたがそれを再キャストするとき、それはそれを新しい形にするためにそれを「コンクリートを注ぐ」ことであり、それはあなたがキャストですることです。六角形の整数として数値があり、キャスト後、長方形の文字列が得られます。


2
また、「(特定の役割を(アクター)に割り当てる」)。
ケリートーマス14年

うん。これが最高だと確信しています。+1。
david.pfx

2

Cキャストを2つのグループに分けると便利な場合があります。

  1. 数値キャスト-数値をある表現から別の表現に変換し、値を保持しようとします。たとえば-に(int)3.1なります3。正確な値を保持できない場合の動作を定義する正確なルールがあります。

  2. ポインターキャスト-メモリアドレスは保持しますが、逆参照の方法を変更します。例えば、のためにfloat x=3.5*(int *)&x与える1080033280-この整数は、浮動小数点を表す同一のビットパターンで表現されます3.5


Keep the memory address, but change the way it's dereferenced.型付きポインタの逆参照は定義されていません。標準では、最初から最後まで逆参照するのに有効ではない可能性がある、またはその逆のキャストが同じものを生成するA *ことのみを保証します。または、ある場合、任意のタイプのオブジェクト表現の読み取りに使用できます。他のすべてのタイプの場合、ポインターの逆参照は、型のパニング、UB、および厳密なエイリアスに違反します。コンパイラは、その理由については、上記の例2をゴミ箱なかった場合でもとにかく、あなたはビットパターンについて移植の仮定を作っているB *A *B *char *B *
underscore_d

1
cast (v): to receive form in a mold

C ++では、reinterpret_cast「これらのバイトを既に他のオブジェクトであるかのように扱う」という意味で、さまざまな種類のキャストをより明確にすることができます。C unionでは、aを使用して絶対に明示的にすることができます。(type)演算子でキャストすると、精度が失われるまで、結果が数値的に同等に保たれます。


2
Cでは、ポインターキャストは常に再解釈され、値キャストは常に可能な限り値を保持します。C ++には、ポインターキャストを行う方法が複数あります。そのため、より明示的なキャスト型があります。
-Jan Hudec 14

Cポインターキャストのセマンティクスは、必ずしも「再解釈」されるわけではありません。ワードアドレッシングを使用しているが、バイトベースのコードとうまくやり取りして、int*1ワードとchar*2ワード(2番目のバイトがワードの上位バイトまたは下位バイトを選択する)を処理したいプロセッサにとっては正当です。(int*)to (char*)をキャストするには、の最初のバイトを指定する値が何であっても、余分な単語を追加する必要がありますint
supercat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.