[英]Java: Subtract '0' from char to get an int... why does this work?
這很好用:
int foo = bar.charAt(1) - '0';
然而這不是——因為 bar.charAt(x) 返回一個字符:
int foo = bar.charAt(1);
似乎從 char 中減去“0”會將其轉換為 integer。
為什么或如何減去字符串“0”(或者它是一個字符?)將另一個字符轉換為 integer?
這是一個聰明的伎倆。 字符實際上與短褲的類型/長度相同。 現在,當您有一個代表 ASCII/unicode 數字的字符(如“1”),並從中減去可能的最小 ASCII/unicode 數字(例如“0”)時,您將得到該數字的相應值(因此,1)
因為 char 與 short 相同(盡管是 unsigned short),所以您可以安全地將其轉換為 int。 如果涉及算術,則轉換總是自動完成的
這是一個古老的 ASCII 技巧,適用於任何從“0”開始按順序排列數字“0”到“9”的編碼。 在 Ascii 中,'0' 是值為 0x30 的字符,而 '9' 是 0x39。 基本上,如果您有一個數字字符,則減去 '0' 會將其“轉換”為它的數字值。
我不得不不同意@Lukas Eder 並認為這是一個可怕的技巧; 因為此操作的意圖從代碼中明顯接近 0%。 如果您使用的是 Java 並且有一個包含數字的String
,並且您想將所述String
轉換為int
我建議您使用Integer.parseInt(yourString);
.
這種技術的好處是對未來的維護程序員顯而易見。
'0'
也是一個字符。 事實證明,Java 中的字符具有 unicode (UTF-16) 值。 當您將-
運算符與字符一起使用時,Java 會使用整數值執行運算。
例如, int x = 'A' - '0';// x = 17
char
被隱式轉換為int
:
public static void main(String [] args) throws Exception {
String bar = "abc";
int foo = bar.charAt(1) - '0';
int foob = bar.charAt(1);
System.err.println("foo = " + foo + " foob = " + foob);
}
輸出: foo = 50 foob = 98
。
也許你放了兩個int foo ...
這是因為它不起作用?
下面的代碼工作得很好!
int foo = bar.charAt(1);
與引用類型類似,任何 Java 原語都可以在不強制轉換為它被視為其子類型的類型的另一個原語的情況下進行分配。 JLS 第 4.10.1 節給出了原語的子類型規則。 char
被認為是int
的子類型,因此任何char
都可以分配給int
。
您的代碼可能會編譯而不會出錯並運行而不會引發異常,但是在 char 和 int 之間進行轉換是不好的做法。 首先,它使代碼混亂,導致后續的維護問題。 其次,巧妙的“技巧”可以防止編譯器優化字節碼。 獲得快速代碼的最好方法之一是編寫愚蠢的代碼(即,不是聰明的代碼)。
因為在 Java 中,如果您不指定帶有數字的類型指示符,則它假定為 Integer。 我的意思是,如果你想設置一個 Long 值,它需要是 0L。
對兩個不同的數值進行數值運算,結果取較大者。 因此,一個字符(它是一個數值)減去一個整數,結果是一個整數。
你會發現這也有效
long val = bar.charAt(1) - 0L;
不過,您的第二個剪輯應該可以正常工作:
int foo = bar.charAt(1);
一個char
,就像一個short
或byte
,如果需要,總是會被默默地轉換為int
。
這將編譯得很好: int i = 'c';
如果人們忽略他的評論,我將回應@Mark Peters 上面所說的內容。
正如我引用的:“不要誤以為 '0' == 0。實際上,'0' == 48”
'5' 的整數值為 53
如果我們寫 '5'-'0',它的計算結果為 53-48,或者 int 5
如果我們寫 char c = 'B'+32; 然后 c 存儲 'b'
'b' = 98。
請參考 ASCII 圖表https://en.cppreference.com/w/cpp/language/ascii
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.