C言語関係掲示板

過去ログ

No893 キャストについて

[戻る] [ホームページ]

※ 投稿者による質問の削除が行われたため、回答のみのログになります。

No.542

Re:キャストについて
投稿者---YuO(2003/10/20 02:07:08)


>疑問1
>int a,b;
>(double)(a+b)/2;
>このような場合にキャストは確かに便利だと思うのですが、なんとなく
>プログラムのような厳密な世界には不適切な気がします。
>double a,b;とすれば良いだけなのにどうしてキャストという逃げ道(?)が用意されているのですか?

本質的に異なるものの橋渡しをするためです。

例えば,あるテストの平均点を出すとします。すると,
・個々の得点は整数
・合計点も整数
・平均点は小数
となります。
#中には得点が小数のテストもあるでしょうけど,それは考えない。

ここで,合計点から平均点を出すときに,
明示的にしろ暗黙的にしろ,キャストが必要になります。


>疑問2
>void * というどんな型のポインタでも入れることが出来るものがあるそうですが、これもその後に何らかの処理をするために別の型にキャストする必要があることがしばしばあると思います。
>なのにどうしてvoid *なるものが存在するのですか?

void *は「型が不明のオブジェクトへのポインタ」とか,
「記憶域の塊」を表すのに利用します。

例えば,malloc関数が
char * malloc (size_t);
のように宣言されていたり,memcpy関数が
char * memcpy (char *, const char *, size_t);
のように宣言されていると,関数を使うたびに引数や戻り値でキャストを必要とします。


>疑問3
>int型からdouble型へはキャストできますが、構造体A型を指すポインタから構造体B型を指すポインタへはキャストできないと思います。

できますよ。


>そうだとすると、何型から何型へキャストできるのでしょうか?
>キャストできる型とは何なのでしょうか?

変換が存在する型同士でキャストができます。
1. cv修飾子を除いた部分が同じ型同士
2. 算術型同士
3. 任意の型からvoid型へ
4. 整数型とポインタ型
5. オブジェクト型または不完全型へのポインタ型からオブジェクト型または不完全型へのポインタ型
6. 関数へのポインタ型から関数へのポインタ型


C言語のキャストには,3つの意味があります。
a. cv修飾の変更 (1)
b. 値の変換 (2, 3)
c. ポインタが指すオブジェクトの型の変更 (4, 5, 6)

たいていの場合,特にaとcは使わなくても済むのですが,
システムの都合上使わざるを得ない場合があります。
#Windowsのメッセージなんか酷い状況です。


No.545

Re:キャストについて
投稿者---YuO(2003/10/20 10:47:30)


CStringということは,C++言語でしょうか?
C++言語を使っているなら,その旨記述して下さい。
CとC++では非互換な部分がありますから。


>疑問1
>例えば、
>CString* a;
>a=(CString*)("123");
>はできませんよね。

できます。とりあえず,
struct foo;
int main (void) {
    struct foo * p;
    p = (struct foo *)("123");
    return 0;
}

というプログラムを,
・Borland C++ 5.5.1 for Win32
・Microsoft(R) 32-bit C/C++ Standard Compiler Version 13.00.9466 for 80x86
・Digital Mars Compiler Version 8.35n
のCモードおよびC++モードでコンパイルして,エラー無しにコンパイルできることを確認しました。
#BCCはpの値が使われていない,という警告が出たけど。

規格上も上のプログラムに問題はないはずです。
#C++は旧規格(ISO/IEC 14882:1998)準拠。


>疑問2
>また、
>CString* a ;
>a = (CString*)f(x) ;
>が、成り立つのはf(x)がCString*を返す時だけだと聞いたのですが、違うのでしょうか?
>実際にはvoid *が返っているのでCString*にキャストしています。

f(x)が例えintを返しても,
a = (CString *)f(x);
は文法上の全ての制約をパスします。
ただし,aが指すオブジェクトがCStringでない場合,
本来の型と異なる型として扱っているのですから,
オブジェクトとして役に立つかというと疑問ですが。

ついでに,C++言語だと,f(x)がCStringの派生型へのポインタを返す場合,
キャスト無しでaに代入できます。


でもって,C++言語においてはC言語由来のキャスト演算子ではなく,
C++言語固有のキャスト演算子を使うとよいです。

>>C言語のキャストには,3つの意味があります。
>>a. cv修飾の変更 (1)
>>b. 値の変換 (2, 3)
>>c. ポインタが指すオブジェクトの型の変更 (4, 5, 6)

a.のキャストを行うにはconst_cast演算子を,
b.のキャストを行うにはstatic_cast演算子を,
c.のキャストを行うにはreinterpret_cast演算子を,
それぞれ使います。
#というか,それぞれのキャスト演算子を念頭に3つに分けた。


No.549

Re:キャストについて
投稿者---YuO(2003/10/20 22:20:18)


>そこで質問なのですが、intからdoubleへのキャストは数字どうしなので役に立ちますよね。
>また、本来CString*であるものをvoid*で返された場合にCString*にキャストすることも役立ちますよね。
>それ以外に役に立つキャストとはどのような場合があるのでしょうか?

基本的に,役に立つキャストはC++のstatic_castに相当するキャストです。
#void *とポインタ型とではstatic_castで可能。

C++だと,dynamic_castが役に立つこともあるでしょう。


他のキャストは,基本的に切羽詰まった状況,
例えば,ライブラリの仕様上仕方の無いとき等でのみ使うものです。

No.562

Re:キャストについて
投稿者---YuO(2003/10/22 22:58:32)


だれかわかるかな,と待っていたのですが……。


>例3
>具体的にどのような場合でしょうか?

何の話でしょうか?
具体的も何も,何に関して具体的に書けばいいのか全くわかりません。

私や他の方の発言に対応するのであれば,勝手に番号付けせずに,
対応する部分を引用して下さい。