
No.3ベストアンサー
- 回答日時:
キャストはC言語で型の変換を明示的に行うための手段ですね。
また、(void)printf("hello");のように関数の返り値を利用しないことを明示するのにも使われます。しかし、void*ができて以降、C言語では前者の目的でキャストを使う必要はないのではないと思います。仰る通り、前者の使用用途では「違う型の変数への代入だけど、これは意図したことですよ」ということにも使えます。でも、型変換は代入だけではなく関数の引数となる時も使われるので必ずしも代入とは限りません。
なお、C++と違ってC言語ではvoid*がすべてのポインタに明示的にキャストせずに行き来できるので、近頃はほとんど前者の目的でキャストをしていません。今すぐ使用例として思い浮かぶのはネットワークプログラムを書くときに使うこれくらいでしょう。
| bind(listening_socket, (struct sockaddr *)&sin, sizeof(sin))
しかし、これもPOSIX.1準拠の書き方をすると不要ですから、今時キャストの出る機会は関数の返り値を利用しないことを明示するときくらいでしょうね。昔のmallocの返り値はchar*だったのでキャストが必要でしたが、今時mallocの返り値はvoid*なのでキャスト不要ですし、memmoveのsrc、dstともにvoid*ですし、pthread_createの各スレッド関数がもらう変数はvoid*ですから巷で見かけるキャストの多くは無駄にキャストしていると思います。むしろ、キャストを使ったプログラムを見たら変にC++にかぶれた人が書いたプログラムか、void*がなかった頃の古いプログラムか、単なるキャストの練習かと思ってしまいます。
キャストはC言語の機能でも強力な機能の一つで、下手に使うとコンパイラによる型チェックを壊してバクを見つけにくくするので使わないに越したことはないです。もし、どうしても使わないといけないとしたら設計が間違っていないかもう一度確かめたほうがいいと思います。
他の言語でもキャストは型チェックを弱める強力な言語機能であり、バグの温床なので避ける方向に行っていると思います。C++の場合、実務のコーディング規則ではC言語風の何でも変換できてしまうキャストは許可されないはずです。JavaでもGenericsをいれたあたりでキャストがなくてもほとんどのプログラムが書けるようになったと思いますしね。
No.9
- 回答日時:
一応書いておくと...
関数原型(プロトタイプ)がない関数を呼び出す場合、実引数をキャストしても、既定の実引数拡張によって無意味になる場合があります。
具体的には、関数原型のない関数 foo を呼び出す際に、
foo((char)a, (char)b);
のようにchar型にキャストしたとしても、既定の実引数拡張によって、各実引数は通常int型に暗黙的に型変換されます。
ただし、sizeof(char) == sizeof(int) かつ char型が符号無しの処理系では、int型ではなくunsigned int型に型変換されます。
No.8
- 回答日時:
プロトタイプ宣言の無い関数への引数の受け渡し時にもコンパイル結果が違ってきます。
例えば
char foo(char a, char b)
{
return a + b;
}
と言う関数があった場合、他のソースからこの関数を呼び出す時にプロトタイプ宣言していないと
int x, y;
x = foo(1, 2);
と呼び出すと期待した動きをしませんが、
y = foo((char)1, (char)2);
だと正常に動きます。
ただ、キャストの問題というよりもプロトタイプ宣言は必ずしましょうという例ですが。
No.7
- 回答日時:
> そうすると疑問があります。
> ・objには各変数の型情報があるのでしょうか?
> ・もしくはコンパイラに「この計算は浮動小数点型で行う」という意味で解釈され、
> 変換されるのでしょうか?
> (浮動小数点演算という意味のアセンブラに変換されて、バイナリになる?)
コンパイラの出力結果を調べてみるのが、一番納得できると思います。
No.6
- 回答日時:
「ふつ~のプロセッサ」だと, 整数演算と浮動小数演算とでは異なる命令です.
No.4
- 回答日時:
> 「違う型の変数への代入だけど、これは意図したことですよ」
> ってことを分かってもらうための手段という認識でよろしいでしょうか?
違います。
もしそうだとすると、次のような例は説明がつきません。
int a = 1;
int b = (double)a / 2 * 2;
回答ありがとうございます。
(double)a / 2 で左辺がdouble型であるため、1.0 / 2.0となり
結果が0.5になって、0.5 * 2で変数bは1になると思います。
そうすると疑問があります。
・objには各変数の型情報があるのでしょうか?
・もしくはコンパイラに「この計算は浮動小数点型で行う」という意味で解釈され、
変換されるのでしょうか?
(浮動小数点演算という意味のアセンブラに変換されて、バイナリになる?)
どなたか教えてくださいませ。
No.1
- 回答日時:
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
VBAにてcolorindexを変数に格納...
-
typedefをプログラム中で解除す...
-
「#undef」と「#define」の使い...
-
プログラミング言語の変数と数...
-
命名規則 VB 構造体
-
VBAの変数のデータ型を変更する...
-
値が変わるのはどうしてでしょ...
-
関数から配列を返すには?
-
C言語 配列の長さの上限
-
ビットをローテートするプログ...
-
C言語・要素除去
-
C言語のintとcharの違いってな...
-
配列を使わずに、変数名を動的...
-
クイックソートしながら重複要...
-
配列の要素数に変数を入れたい...
-
char*を初期化したいのですが
-
【速いブラインドタッチ】手を...
-
DLLのマルチスレッドの動作につ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
「#undef」と「#define」の使い...
-
VBAの変数のデータ型を変更する...
-
typedefをプログラム中で解除す...
-
値が代入されてない時
-
構造体のデータを丸ごとコピー...
-
VBAにてcolorindexを変数に格納...
-
整数から16進数への変換 現在c...
-
long型のデータをバイト型の配...
-
変数の初期化について
-
1バイトデータの読み出しについて
-
命名規則 VB 構造体
-
異なる構造体のデータのコピー
-
VBAで符号無し整数
-
C言語 構造体の中に共用体を定...
-
日付チェック関数について
-
構造体のポインタにNULLが入らない
-
VBAで変数定義を変更する方法
-
ビット演算について
おすすめ情報