- PR -

char型への代入について

1
投稿者投稿内容
未記入
会議室デビュー日: 2008/04/03
投稿数: 3
投稿日時: 2008-04-03 17:51
はじめまして、Java初心者です。

char型変数への代入について分からないことがありますので
お力をお借りしたいと思い投稿させていただきます。

ソースコード
1行目  char c1 = (int)1.1; //代入可能

2行目  double d = 1.1;
3行目  char c2 = (int)d; //コンパイルエラー

下記はコンパイルエラーの原因です。
「Type mismatch: cannot convert from int to char」

1行目は可能なのに3行目でエラーとなるのはなぜでしょうか?
ご教授よろしくお願いいたします。
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2008-04-03 19:18
1行目と同じ書き方でも

char c1 = (int)65536.1;

これはエラーになりますよね。
コンパイル時点で代入可能な値なのかどうかを、決定できるかどうかの違いでは。
未記入
会議室デビュー日: 2008/04/03
投稿数: 3
投稿日時: 2008-04-04 00:52
ご回答ありがとうございます!

引用:

mioさんの書き込み (2008-04-03 19:18) より:
1行目と同じ書き方でも

char c1 = (int)65536.1;

これはエラーになりますよね。
コンパイル時点で代入可能な値なのかどうかを、決定できるかどうかの違いでは。



確かにchar型変数に代入できる整数の値は0〜65535までで
3行目ではmioさんのサンプルコードと同じコンパイルエラーが
出ています。

ですが、同じ値(1.1)をキャストして代入するのに3行目では
コンパイルエラーになる理由がわかりません。

1行目と3行目の違いは、
 1行目:「リテラルをキャストして代入」
 3行目:「変数をキャストして代入」
の2点です。

おそらく、変数をキャストして代入するのでコンパイルエラーになるのではと
考えているのですが明確な答えがでません。

ご回答よろしくお願いいたします。
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2008-04-04 02:26
引用:

未記入さんの書き込み (2008-04-04 00:52) より:
ですが、同じ値(1.1)をキャストして代入するのに3行目では
コンパイルエラーになる理由がわかりません。

1行目と3行目の違いは、
 1行目:「リテラルをキャストして代入」
 3行目:「変数をキャストして代入」
の2点です。

おそらく、変数をキャストして代入するのでコンパイルエラーになるのではと
考えているのですが明確な答えがでません。



#Javaの言語仕様でこういうパターンについてどう扱われるか?という規定があるかどうかは調べていません。以下は私の個人的な予想です。

おっしゃっる通り、変数をキャストしているからコンパイルエラーになるのだと思います。

変数をキャストする場合でも、その変数の値が事前にcharに代入できる値とわかるならコンパイルを通るようにコンパイラを作るとしたら、そのコンパイラはどんなプログラムを組むことになるか考えてみてください。
人間が2行目と3行目を見て「変換できるじゃないか」と判断するのは瞬時にできますが、コンパイラがそのような判断を行うのはそれなりに手間が掛かります。

コンパイラが3行目のようなコードを見つけた場合、そこで使用されている変数(ここではd)の生い立ちからchar変数への代入までを追跡しないといけません。その上で、その過程で変数に定数式しか代入されていないことを確認する必要があります。

いかにもめんどくさそうですね。私ならやりたくないです。
「変数のキャストでも値がcharに代入可能と判断できるならキャストできるものとする」という仕様を実装するコスト(デメリット)に比べて、メリットがないと思います。
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2008-04-04 07:00
私も言語使用なぞまったく見ていませんし、検証もしていません。
とりあえず想像で書いてみます。

1行目と3行目の違いは即値のキャストか double の変数のキャストかの違い
だと思いますが、1行目の即値が double であるという保証はどこにもない
わけですよね。

もしかしたらだけど、即値で書いたら float として処理されていて、たまたま
float を int にキャストしたら成功したけど、double のキャストはダメとか
そういう話かもしれない、と思いました。

これはよねKENさんも書かれていますが、そもそもこういう書き方はしません
し、私もやりたくありません。無用なバグを増やしてしまいそうですし。
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2008-04-04 07:37
言語仕様にちゃんと書いてありますよ。

5.2 代入変換
http://www.y-adagio.com/public/standards/tr_javalang/5.doc.htm#170768

違いは「(int)1.1」は int 型の定数式なのでプリミティブ型の縮小変換が可能であるのに対し、「(int)d」は定数式ではないので変換が許されないということです。
未記入
会議室デビュー日: 2008/04/03
投稿数: 3
投稿日時: 2008-04-04 21:55
皆さま、たくさんのご回答ありがとうございます!
おかげさまでしっかりと理解することができました!

コンパイラができることについても良く理解することができましたし
これからは言語仕様についても勉強していこうと思います!
1

スキルアップ/キャリアアップ(JOB@IT)