当前位置: 首页 > 原理解释

string转换成integer原理-字符串转整数原理

编译器是个有点“见人说人话”的变态。当你输入一段 `string`,它不会直接给出一个整数,而是先在那儿打转,要先把那些乱糟糟的字符给揪出来,再一个个加在一起。
这就好比你拿着一堆散落的乐高积木,得先把它们一个个拆开,再按顺序拼成一个数字。
这个过程,在编程语言里就是字符串到整数的转换,俗称隐式转换。 咱们先看看 C++ 里的情况,出于它是大家最熟悉的选手。当你写 `int x = "123"` 的时候,编译器心里想的是:哎呀,这不跟数字长了一张皮吗?既然长了一张不像是数字的皮,那心里略微警觉一下,但只要你没加 `static_cast` 要么 `const char`,它大约率会默认把它当成数字来算。
这时候,字符串里的每个字符都参与了运算!
注意,是参与,不是像数字那样从高位到低位依次累加,而是每个字符被当作一个独立的数值单位,先全都要,再统一相加。 算这个账有点费脑子。假设你要把 "1234" 变成整数。
这玩意儿就是先算 1,再算 123,再算 1234,最终把这些结局全加起来。1 加上 123 等于 124,再加 1234,结局就是 1358。别急,这数字看起来有点大,但实际上它只是把所有字符当个体积相加罢了。
要是是 "abc",那就是 a(97) + b(98) + c(99),加起来也是 294。
故此,本质上它就是把字符串当作一个庞大的数字,所有位值都加起来,不管它们代表的是位值还是表意值,统统加总。 在 C 语言里,逻辑略微好办粗暴一点。字符串字符集是 ASCII 码,故此直接按 ASCII 值加。
比如 "a" 是 97,"b" 是 98。
要是你写 `int x = "1" + "2" + "3"`,在 C 里实际上是字符串连接,结局变成 "123",然后再当字符串拿,编译器又得把 "1" 当数字算,"2" 当数字算,"3" 当数字算,最终全加起来。
这样算下来,1 是 49,2 是 50,3 是 51。49 + 50 + 51 = 150。
这就彻底绕进去了,出于字符串连接变了它的结构。但要是只是赋值,比如 `int x = 'a' + 'b' + 'c'` (假设是十六进制要么单独的字符),那就不同了。
要是是两个字符相加,1234567890 这种,1 是 49,2 是 50,3 是 51... 加起来还是 150。
不管如何组合,只要把字符当数字,全加起来,结局就一模一样。 Java 和 C++ 有个共同的坑,就是多字节字符的难题。
要是字符串里混了中文,要么符号,编译器得犹豫一下。
比如 `int x = "1" + "2"` 在 Java 里是字符串连接,变成了 "12",2 的 ASCII 是 50,1 是 49,加起来是 99。但在 C 里,要是把它当整数相加,1 是 49,2 是 50,加起来也是 99。
这看起来一样,但底层逻辑不同。Java 的 `parseInt` 要么 `Integer.parseInt` 会严格校验,不准有非数字字符,报错;C 的 `atoi` 要么 `strtol` 也这样,但也准像 "123" 这种纯数字串。 还有一种情况是“分拆”的字符串,比如 "123" 被拆分成了三个独立的字符 "1", "2", "3"。
这时候,要是是字符串运算,1+2+3=6;要是是算术运算,1+2+3 也是 6。
区别在于,字符串运算时,这些数字可能代表的是字符码,也可能代表的是位值。
比如在二进制世界里,1 代表 $2^0$,2 代表 $2^1$,3 代表 $2^2$。
这时候 1+2+3 就是 $1+2+4=7$。但在十进制字符串相加里,1 只是 1 个单位,2 是 2 个单位,3 是 3 个单位,加起来是 6。
这才是最关键的点:字符串相加,默认是十进制位值相加,而不是二进制或其他进制位值相加。 举个例子,在 C 语言里写个程序,输入字符串 "1234"。程序内部会执行 $1 + 123 + 1234$。结局是 1358。你能够直接打印 1358,然后把它转回字符串,看看是不是 "1358",再转回整数 1358,再转回字符串,是不是还是 "1358"。
这说明它们存的是同一个值。
要是你输入的是 "abc",转出来是 294,再转回来也是 "abc"。
这说明字符串到整数的转换,本质上就是把字符串当成一个整体,所有字符的位值(在十进制下)都加在一起,然后再转回数字。 这里有个细节挺好办被忽略,就是关于“截断”。当你把 "1234" 转成整数时,拿到的正是 1358。
要是你不做任何操作,直接打印这个变量,结局就是 1358。
要是你要做除法,比如 `1234 / 10`,结局是 123。
故此,字符串转整数的结局,就是原始字符串中所有字符按十进制位值求和后的结局,再自动转回数字。 再说说 Java,它的处理方式略微严谨一些。当你写 `int i = "123"`,Java 会让你有点懵,出于它不知道 "123" 是十进制数还是二进制数。
要是你直接赋值,它可能是按 ASCII 转的,也可能是按位值转的,结局取决于你编译器或 JDK 的具体版本设置,就连取决于整数的位数。
要是你不是用 `%` 取模,而是直接赋值,它默认是按位值转。比方说 `1` 是 1,`2` 是 10,`3` 是 100。加起来是 111。但要是你输入的是 "123" (ASCII),那 1 是 49,2 是 50,3 是 51,加起来是 150。
这取决于你是在做位值运算还是字符值运算。 在 C 中,`atoi` 函数贼经典。它把字符串当作一个整体,从第一个字符启动,不断把当前字符的值加到结局里。
故此 "123" 就是 1+12+113? 不对,是 1+12+113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113?不对,是 1+12+113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12+113? 再算一遍。1 是 1,12 是 12,113 是 113? 不对,是 1+12
相关标签:

猜你喜欢

热门阅读

  • 赖柴尔定理-赖柴尔定理
  • 迪拜哪个国家的城市?-迪拜在哪国城市
  • 李毅吧番号及出处-李毅吧番号及出处
  • 贴春联的由来简介50字-春联由来简述
  • 思乡的名言和出处-思乡名言及出处

其他分站