• ベストアンサー

char型変数

のことで質問があります。 ユニコード文字一文字ということなんですけれども、 たとえば char c = "a"; これはコンパイルエラーになりますよね。 文字列は入れられない。もっともです。 あるテキストの練習問題で、コンパイルエラーになるものはどれですかというのがあって、 char c = 4096; というのがあり、これはエラーだ!、と思ったら、 コンパイルは通りました・・・ ちなみにcの内容を表示してみたら ? と出ました。 これはどういうことですか?? なぜエラーとならないのですか?

質問者が選んだベストアンサー

  • ベストアンサー
  • lawson
  • ベストアンサー率44% (29/65)
回答No.10

>これは >temp = temp & 0xfffffffffffffff8L; >と同じですよね・・・? 同じです。 以上

azicyan
質問者

補足

ありがとうございました!! とても助かりました!!

その他の回答 (9)

  • lawson
  • ベストアンサー率44% (29/65)
回答No.9

long l = 2147483648; は 整数 2147483648 が大き過ぎます。 long l2 = 2147483648; ^ エラー 1 個 というエラーになってしまいます。 long l = 2147483648L; ならば、OKです int型の最大値は2147483647だからです。 http://java.sun.com/j2se/1.3/ja/docs/ja/api/index.html を見てください。 public static final long MAX_VALUE long 型の最大値です。 という部分があります。 このラッパークラス Long自作するなら、 MAX_VALUEの初期値として, ~L をコーディングする以外に方法はありません。 2147483647 よりも大きな定数を使う必要が ある場合は~Lとするしかないです。 その例としてもうひとつ ビット演算等を行う必要がある時などでしょうか。 ある64ビットのビット列をlong型に格納していると します。 たとえば、long型変数、tempにビット列がはいっている とします。 下位3ビット(一番左のビット)だけゼロにして、 それ以外のビットは、元のビットのままにする 操作がしたいとします。 temp &= 0xfffffffffffffff8L; とするでしょう。 これも~Lをつけるなければ、無理です。 あと、 たとえば、 あるクラスAの中で、以下のオーバーロード されたメソッドがあるとします。 public void foo(int i); と public void foo(long i); というメソッドがあったとします。 A a = new A(); a.foo(5); では上が実行されます A a = new A(); a.foo(5L); では下が実行されます。 値がどうあれ、型の違いが重要な時は、 意図的に~Lをつけるでしょう。 今、ぱっとおもいつく~Lの用法はそんなもんです。

azicyan
質問者

補足

>long l = 2147483648L; >ならば、OKです >int型の最大値は2147483647だからです。 普通に数字を入力するとINT型であるので、 Lをつけなきゃならない、ということですね。 (このあたり油断すると意味がわからなくなりそうです・・・(^_^.)) >temp &= 0xfffffffffffffff8L; これは temp = temp & 0xfffffffffffffff8L; と同じですよね・・・? >public void foo(int i); と public void foo(long i); というメソッドがあったとします。 A a = new A(); a.foo(5); では上が実行されます A a = new A(); a.foo(5L); では下が実行されます。 これはすごくわかりやすいです。 ありがとうございました!

  • lawson
  • ベストアンサー率44% (29/65)
回答No.8

>すいません新しい疑問が・・・ >>c = 0x61L; >とはどういうことなのでしょうか? >ロング型だからエラーというのはわかるんですが、 >0x61のロング型・・・??? >0~65535の間ならいいんですよね・・・? >ロング型だろうと、0x61は0~65535の間に入っているよう>な気が・・・?? >深>考えすぎですかね? いえ、消して深く考えすぎではありません。 何事も基本が重要です。 小さいことでも、疑問を解決しようとする その、探求心はすばらしいです。 都度私の回答のNo6を見るなりして理解しようとがんばって ください。 話を単純化するため、 基本データ型についてに限定しますが・・。 もう一度、補足します。 型は変数だけでなく、定数にも存在します。 小さな型の変数 = 大きな型の定数または変数; というような代入を行う際には javaにおいては、 小さな型の変数 = (小さな型)大きな型の定数または変数; のように,小さな型にキャストしてから、代入しないと、 コンパイラに怒られてしまいます。 この時、コンパイラがチェックしているのは 型の整合性です 実際に実行時に格納される値が"小さな型"におさまる 範囲であるかはコンパイラにはわからない話です。 これを踏まえた上で説明します。 0x61 や 97 は はint型の定数です 16進数で表記しようと、10進数で表記しようと、 整数の定数は、接尾子をなにもつけなければ、 int型の定数になります。 ですから、 int i = 0x61; char c; c = i; 小さな型の変数 = 大きな型の定数または変数; なので、 コンパイルエラーです int i = 0x61; char c; c = (char)i; にすると、 小さな型の変数 = (小さな型)大きな型の定数または変数; なので、 コンパイルできます。 いまは代入演算の右辺の代入する側がint型の「変数」で あったから、通常どおりのキャストが必要なのです ところが、 代入演算の右辺の代入する側がint型の「定数」で あれば、javaの構文上の特別なルールで、 intより小さな型の変数 = int型の定数; は、int型の定数が小さな型を超えなければ 構文上許されるようです。 このルールの時はコンパイラは実際の値 の内容がintより小さな型に収まるものなのかを ちゃんとチャックするようです。 ですから、 No7 で説明したように char c = 0x61; は char c = (char)0x61; としなくても、(別してもいいですが) コンパイルおよび実行できます。 しかし char c = 0x61L; とした場合 コンパイルエラーになります なぜなら、0x61L は接尾子 L がついているため long型の定数です。値の内容がどうであるとかは 関係ありません。値の内容がどうあろうと、 long型の定数です。 なので、 javaの特別ルール intより小さな型の変数 = int型の定数; には該当しないものになりますので、 通常どおりのキャストのルールにのっとった 形にする必要があります。 char c = 0x61L; では 小さな型の変数 = 大きな型の定数または変数; なので、 コンパイルエラーです char c = (char)0x61L; であれば、 小さな型の変数 = (小さな型)大きな型の定数または変数; であり、コンパイルできます。 あと、余談ですが・・。 キャストしてコンパイラの型チェックさえ、通過して しまえば、実行時に0~65535を超過してオーバーフロー を起こしても特にエラーにはならないです。 char c = (char) ( 65535L + 0x61L + 0x01L); System.out.println(c); は小文字の a が画面に表示されます 65535 に1と足すと一回転してゼロにもどります さらに0x61を足すので、そうなります。 きのすむまで、 ゆっくり、考えて理解してみてください 以上

azicyan
質問者

補足

たくさんありがとうございます。 とても助かります。 さらに疑問が・・・ なんとなく理由はわかってきたんですが・・・ では、わざわざ、INT型でもよいような数値に’L’ をつけて、Long型とする理由は何でしょうか?? 理由というか、メリット?はあるんでしょうか? ただ単に、JAVACではこういうのはえらーとしてはじかれるよ、という実験なのでしょうか??

  • lawson
  • ベストアンサー率44% (29/65)
回答No.7

NO6です いかの内容に回答するのを忘れていました。 >char c = "a"; >これはコンパイルエラーになりますよね。 >文字列は入れられない。もっともです "a"と'a'は異なります。 "a"はStrin型のオブジェクトであり、参照型です。 参照型と基本データ型との間では いかなる型であろうとも、代入互換性はありません。 たとえ、Object型に対してさえも、基本データ型を 代入することは、不可能です。 >ちなみにcの内容を表示してみたら >? と出ました。 >これはどういうことですか?? >なぜエラーとならないのですか? たとえば、4096番に該当するコードが世界のどこかの 国のコードなどで、azicyanのPCには そのコードに対応する文字を認識することができないの かもしれません。 4096の部分を28450に変えてみてはいかがでしょうか おそらく 漢 という文字が出力されると思います。 あと、 No6で説明した (char)0x61や(char)97は別に キャストしなくても 0x61をchar型定数に格納できます。 char c = 0x61; や char c; c = 0x61; はできます。 これはint型の整数定数に関しての特別な ルールのようです ちなみに、 long型定数で char c; c = 0x61L; をすると、エラーです また、int型であっても、変数からの代入に 関しては、通常どおりキャストが必要です 以下はエラーになります。 int i = 0x61; char c = i; 以上

azicyan
質問者

補足

4096の部分を28450に変えてみてはいかがでしょうか おそらく 漢 という文字が出力されると思います。 でました! >たとえば、4096番に該当するコードが世界のどこかの 国のコードなどで、azicyanのPCには そのコードに対応する文字を認識することができないの かもしれません。 この説明よ~くわかります!! すいません新しい疑問が・・・ >c = 0x61L; とはどういうことなのでしょうか? ロング型だからエラーというのはわかるんですが、 0x61のロング型・・・??? 0~65535の間ならいいんですよね・・・? ロング型だろうと、0x61は0~65535の間に入っているような気が・・・?? 深く考えすぎですかね?

  • lawson
  • ベストアンサー率44% (29/65)
回答No.6

char型とは文字型のように見えますが その正体は符号なしの16bitの整数型のこと なのです。 符号なしの16bitの整数型なので、 プログラマはchar型変数に 0~65535までの数値を格納することができます。 ##################################### 整数型となっている基本データ型について 示します。 byte型 8bit 符号あり整数 -2^(8-1) ~ 2^(8-1) - 1 で -128~127 short型 16bit 符号あり整数 -2^(16-1) ~ 2^(16-1) - 1 int型 32bit 符号あり整数 -2^(32-1) ~ 2^(32-1) - 1 long型 64bit 符号あり整数 -2^(64-1) ~ 2^(64-1) - 1 char型 16bit 符号なし整数 0 ~ 2^(16) で 0~65535 ##################################### 話を単純にするために、参照型については ここでは考慮せずに基本データ型のみを 考えて、説明を続けます。 型は、変数だけでなく、定数にもあります。 'a' は (char)0x61 と (char)97 と '\u0061' はほぼ(あくまでほぼ)同じ意味だといえ 0~65535の範囲内なので、 char型の変数に格納することが可能です 'a' はchar型の定数です '一文字' はCではint型の定数ですが、 C++, JAVAではchar型の定数 ちなみに、C++, JAVAではchar型の意味が ことなりますが・・・ (char)0x61 0x61というint型の定数をchar型にキャストしています。 整数定数のデフォルトはint型です。 0x61L など、接尾子をつけるとlong型定数になります。 0x61は負の数でく、かつ、0x61自体が 0~65535の範囲ないにあるので、 (char)0x61をchar型変数に代入しても情報が 失われることはないでしょう。 (char)97 は単に、表現形式が10進数になっただけで、 (char)0x61 と同じです。 '\u0061' はcharが定数であり、 'a'が文字を指定するのにたいして、 UNICODE値を指定する方法です。 UNICODEであってもASCIIの範囲は同じ コードと文字がマッピングされていますので、 '\u0061'は'a'と同じく char型変数に代入可能です 以上

azicyan
質問者

補足

ちょっと難しいですが、 よく読んでみます。 ありがとうございました!

回答No.5

再びNo.3です。 先程のURLに補足です。 メニューのユニコード欄にある、 UTF-8 (特化無) を選択して下さい。

参考URL:
http://code.cside.com/3rdpage/jp/
azicyan
質問者

補足

うーん。 どうやってみるんでしょう・・・

回答No.4

No.3です。 先程は意地悪な回答で失礼致しました。 下記URLのユニコード表を参考にして下さい。 下を試すと、 64 65 と出力されませんでしたか? 表で見ると 'A'は0041(16進)=64 'B'は0042(16進)=65 です。 >ためしに、 >char a = 'A'; >char b = 'B'; >という変数を作成し、 >System.out.println((int)a); >System.out.println((int)b); >とその文字をintにキャストして出力してみて下さい。

参考URL:
http://code.cside.com/3rdpage/jp/
azicyan
質問者

お礼

ありがとうございます。 逆にa=64;b=0x42; のようにすると A,Bと出ますね! だんだんわかってきましたよ!

回答No.3

ためしに、 char a = 'A'; char b = 'B'; という変数を作成し、 System.out.println((int)a); System.out.println((int)b); とその文字をintにキャストして出力してみて下さい。 これでヒントになると思うのですが。

azicyan
質問者

補足

65,66 と出ました!

  • kaz_iwa
  • ベストアンサー率27% (10/37)
回答No.2

ごめんなさい配列はint系でしたね

azicyan
質問者

補足

いいえ~

  • kaz_iwa
  • ベストアンサー率27% (10/37)
回答No.1

4069が char c の配列に入っているからではないでしょうか? c[0] は 4 c[1] は 0 c[2] は 6 c[3] は 9

azicyan
質問者

補足

お早い回答畏れ入ります 早速やってみました。 とりあえずc[0]を見てみようということで・・・ 配列が要求されましたが、char が見つかりました。 System.out.println(c[0]); というエラーです。 ちょっと違うようです・・・