アプリ版:「スタンプのみでお礼する」機能のリリースについて

のことで質問があります。
ユニコード文字一文字ということなんですけれども、

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

と出ました。
これはどういうことですか??
なぜエラーとならないのですか?

A 回答 (10件)

>これは


>temp = temp & 0xfffffffffffffff8L;
>と同じですよね・・・?

同じです。

以上

この回答への補足

ありがとうございました!!

とても助かりました!!

補足日時:2003/12/01 11:11
    • good
    • 0

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/inde …

を見てください。

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の用法はそんなもんです。

この回答への補足

>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);
では下が実行されます。



これはすごくわかりやすいです。
ありがとうございました!

補足日時:2003/11/30 00:09
    • good
    • 0

>すいません新しい疑問が・・・



>>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を足すので、そうなります。

きのすむまで、
ゆっくり、考えて理解してみてください

以上

この回答への補足

たくさんありがとうございます。

とても助かります。

さらに疑問が・・・
なんとなく理由はわかってきたんですが・・・

では、わざわざ、INT型でもよいような数値に’L’
をつけて、Long型とする理由は何でしょうか??
理由というか、メリット?はあるんでしょうか?

ただ単に、JAVACではこういうのはえらーとしてはじかれるよ、という実験なのでしょうか??

補足日時:2003/11/29 09:59
    • good
    • 0

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;

以上

この回答への補足

4096の部分を28450に変えてみてはいかがでしょうか
おそらく 漢 という文字が出力されると思います。


でました!


>たとえば、4096番に該当するコードが世界のどこかの
国のコードなどで、azicyanのPCには
そのコードに対応する文字を認識することができないの
かもしれません。


この説明よ~くわかります!!

すいません新しい疑問が・・・

>c = 0x61L;

とはどういうことなのでしょうか?
ロング型だからエラーというのはわかるんですが、
0x61のロング型・・・???
0~65535の間ならいいんですよね・・・?
ロング型だろうと、0x61は0~65535の間に入っているような気が・・・??
深く考えすぎですかね?

補足日時:2003/11/29 00:35
    • good
    • 0

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型変数に代入可能です

以上

この回答への補足

ちょっと難しいですが、
よく読んでみます。

ありがとうございました!

補足日時:2003/11/29 00:33
    • good
    • 0

再びNo.3です。



先程のURLに補足です。

メニューのユニコード欄にある、
UTF-8 (特化無)
を選択して下さい。

参考URL:http://code.cside.com/3rdpage/jp/

この回答への補足

うーん。

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

補足日時:2003/11/29 00:30
    • good
    • 0

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/
    • good
    • 0
この回答へのお礼

ありがとうございます。

逆にa=64;b=0x42;
のようにすると
A,Bと出ますね!

だんだんわかってきましたよ!

お礼日時:2003/11/29 00:29

ためしに、



char a = 'A';
char b = 'B';

という変数を作成し、

System.out.println((int)a);
System.out.println((int)b);

とその文字をintにキャストして出力してみて下さい。
これでヒントになると思うのですが。

この回答への補足

65,66
と出ました!

補足日時:2003/11/29 00:26
    • good
    • 0

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

この回答への補足

いいえ~

補足日時:2003/11/29 00:23
    • good
    • 0

4069が char c の配列に入っているからではないでしょうか?



c[0] は 4
c[1] は 0
c[2] は 6
c[3] は 9

この回答への補足

お早い回答畏れ入ります
早速やってみました。
とりあえずc[0]を見てみようということで・・・

配列が要求されましたが、char が見つかりました。
System.out.println(c[0]);

というエラーです。

ちょっと違うようです・・・

補足日時:2003/11/28 12:10
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!