70997


条件式はresult[i]の値が0の場合は9としたいのですが、実行したら"20092812345"の0のところが"//"と置き換わってしまいました。  
これはif文の式がいけないのでしょうか？  
どうしてか教えていただきたいです。

**ソースコード**

[code]

    class main {
        public static void main(String[] args) {
            angouka test01 = new angouka();
            System.out.println(test01.net("20092812345"));
    
    
    }
    
    public String net(String in) {
        char[] result = in.toCharArray();
        for(int i = 0; i < result.length; i++) {
    
            if(result[i] == 0) {
                result[i] = 9;
            }else {
                --result[i];
            }
        }
    
        return new String(result);
    }
    
[/code]

**実行結果**

[code]

    1//81701234
    
[/code]


CC BY-SA 4.0
2020-10-07T12:49:07.460
70994
2020-10-07T17:12:12.583
2020-10-07T17:12:12.583
3475
32774
question
java
"0" との比較


文字コードと文字が表している整数値との区別がついていないようです。

この行

[code]

    char[] result = in.toCharArray();
    
[/code]

を実行した後、`result`は、`char`型の配列となり、`{'2', '0', '0', '1',
...}`となるのですが、`char`型の`'2'`と言う値は整数値の`50`、`'0'`と言う値は整数値の`48`を表します。これはJavaが採用しているUnicodeのコード値(UTF-16のコードポイント)になります。

文字コードの`0`は、NUL文字を表しており、普通の文字列中には現れませんから、`result[i] ==
0`という条件は成立せず、常に`else`の側が実行されることになります。

(`'0' == 48`であり、`'0' == 0`は成立しません。)

元の文字が`'0'`の場合、その文字コードは`48`、そこから1を引いた`47`が`result[i]`に入るのですが、それは文字コードとしてはスラッシュ(`'/'`)を表しているので、`'0'`は`'/'`に変換されているのです。

文字として`result[i]`の内容を比較したり、設定したりするのであれば、文字定数リテラル`'~'`を使用しましょう。

[code]

        public String net(String in) {
            char[] result = in.toCharArray();
            for(int i = 0; i < result.length; i++) {
                if(result[i] == '0') {
                    result[i] = '9';
                }else {
                    --result[i];
                }
            }
    
            return new String(result);
        }
    
[/code]

出力:

[code]

    19981701234
    
[/code]


CC BY-SA 4.0
2020-10-07T13:20:12.350
70995
2020-10-07T13:20:12.350
13972
70994
answer


うまくプログラムが作れないのは、文字(char)と整数(int)の区別がちゃんとついていない事にあると思われます。

質問のプログラムが実行されていく過程を追って、確認していきましょう。

mainクラスのmainメソッドで、angoukaクラスの変数 test01の
netメソッドが"20092812345"という文字列を引数として呼び出されます。

[code]

        angouka test01 = new angouka();
        System.out.println(test01.net("20092812345"));
    
[/code]

netメソッドでは、変数resultに、"20092812345"を toCharArrayメソッドで文字の配列にしたものが入ります。  
result の値は、["2","0","0","9","2","8","1","2","3","4","5"]となる訳です。

問題は、for文の中にあります。

[code]

        if(result[i] == 0) {
            result[i] = 9;
        }else {
            --result[i];
        }
    
[/code]

if文の条件は、「result[i] ==
0」となっていますが、result[i]は文字(char)、0は整数(int)ですから、等しくなる事はあり得ません。  
そのため、ループのたびに「--result[i];」が実行されます。

charは、文字を表すコードで表現されます。"0"は、0x30(16進数で30という意味で、ビットで表現すると、00110000)、"9"は、0x3A(ビットで表現すると、00111001)です。  
この文字コードの体系は、"American Standard Code for Information
Interchange"（ASCII)と呼ばれます。ASCIIで表現できる文字は、数字、記号、アルファベットです。ASCIIコードの表へのリンクを下に置きますから、リンクをクリックしてASCIIコード表を見てみてください。

[ASCIIコード表](https://www.k-cube.co.jp/wakaba/server/ascii_code.html)

"0"は、0x30で表されると書きました。  
もし、i=1で、result[i]が"0"の時に、「--result[i];」が実行されると、どうなると思いますか？

"0"(ビット表現で00110000)から1が引かれて、0x00101111(16進数で2F)になります。  
0x2Fは"/"という文字の文字コードです。

これが「0のところが"//"と置き換わってしまいました」という現象が起きた理由です。

具体的には、["2","0","0","9","2","8","1","2","3","4","5"]であったresultの値が、「--result[i];」がループで順に適用されることによって、["1","/","/","8","1","7","0","1","2","3","4"]になった。  
これをprintすれば、「1//81701234」となりますよね。


CC BY-SA 4.0
2020-10-07T13:33:31.443
70997
2020-10-07T13:33:31.443
217
70994
answer