请解释这段代码在做啥(someChar - 48)
Posted
技术标签:
【中文标题】请解释这段代码在做啥(someChar - 48)【英文标题】:Please explain what this code is doing (someChar - 48)请解释这段代码在做什么(someChar - 48) 【发布时间】:2011-03-12 19:44:11 【问题描述】:我正在经历一些练习题,我看到了这段代码:
#include <stdio.h>
#include <string.h>
int main(void)
char* s = "357";
int sum = 0;
int i = 0;
for (i = 0; i < strlen(s); i++)
sum += s[i] - 48;
printf("Sum is %d", sum);
return 0;
谁能解释一下代码的作用,尤其是 48 部分的减法?
【问题讨论】:
【参考方案1】:代码基本上将表示为字符串的数字的数字相加。它做了两个重要的假设才能正常工作:
字符串仅包含'0'..'9'
范围内的字符
使用的字符编码是 ASCII
在 ASCII 中,'0' == 48
、'1' == 49
等。因此,'0' - 48 == 0
、'1' - 48 == 1
等等。也就是说,减去 48 会将 char
值 '0'..'9'
转换为 int
值 0..9
。
因此,正是因为'0' == 48
,该代码也适用于:
sum += s[i] - '0';
这个版本的意图可能更清楚一些。
您当然可以通过添加来进行“反向”映射,例如5 + '0' == '5'
。同样,如果您有一个包含'A'..'Z'
范围内的字母的char
,您可以从中“减去”'A'
以获得该字母在0..25
范围内的索引。
另见
Wikipedia/Digit sum Wikipedia/ASCII相关问题
How to convert a single char into an int Language showdown: Convert string of digits to array of integers? 这种数字转换的许多示例,使用'0'
和 48
的减法!
关于替代编码
如前所述,原始- 48
代码假定使用的字符编码是ASCII。 - '0'
不仅提高了可读性,而且放弃了 ASCII 假设,并且可以使用 any 编码,正如 C 语言所规定的,它规定数字字符必须在一个连续的块中按顺序编码。
另一方面,对字母没有做出这样的规定。因此,在极少数使用 EBCDIC 编码的情况下,例如,将 'A'..'Z'
映射到 0..25
不再像减去 'A'
那样简单,因为字母 NOT 在 EBCDIC 中的连续块中按顺序编码。
一些编程语言通过强制使用一种特定的编码来表示源代码来简化问题(例如,Java 使用 Unicode:JLS §3.1)
另见
Wikipedia/Extended Binary Coded Decimal Interchange Code (EBCDIC)相关问题
Are digits represented in sequence in all text encodings?【讨论】:
+1 指出'0'
在这种情况下写48
会更清晰。 FWIW,使用'0'
也可以使其在EBCDIC 废话上工作(C 保证数字的连续字符值);但是,您的 'A'
示例不适用于 EBCDIC。
这些技巧起作用的原因是因为 ascii 代码是有序的。也就是说,'0' 到 '9' 使用连续的 ascii 代码('a' 到 'z' 和 'A' 到 'Z')。请参阅cdrummond.qc.ca/cegep/informat/Professeurs/Alain/files/… 以获得体面的 ascii 图表。
@R.. C如何保证数字的连续字符值?!它只是碰巧ASCII,作为EBCDIC,有这个属性。如果系统在没有此属性的情况下使用另一种编码,则该代码将无法工作。此类系统不存在这一事实并不会使逻辑无效。
@ShinTakezou,任何没有此属性的字符编码都不是 C 实现允许的编码。或者换一种说法,使用这种编码的自称“C 实现”不会是“C”。阅读标准。无论如何等一两年,ISO C 最终会继续指定 ASCII 或(运气好的话)UTF-8。
@R.. 有趣,谢谢。 (一旦我在这里找到了 std 的链接,但现在我没有了,无论如何我几乎不会阅读它,因为我相信它必须由必须使编译器兼容的人才能阅读,而我,作为业余程序员,信任-std=c99
或类似的...)我不知道任何没有属性的编码...但是如果它存在使用这种编码的系统,有趣的是注意到这样的系统不能有完全符合标准的 C 编译器!【参考方案2】:
求字符串 s 中数字的总和。
sum += s[i] - 48;
将 ASCII 字符转换为其数值。
【讨论】:
【参考方案3】:将 3 + 5 + 7 相加,然后打印
总和是 15
-48
部分是减去字符0,也就是0的ascii值。
所以它的作用是
'3' - '0' > 51 - 48
'5' - '0' > 53 - 48
'7' - '0' > 55 - 48
如您所见,在 C 中,'0'(字符零)与 0(数字 0)不同。他们有不同的价值观(除其他外)
【讨论】:
【参考方案4】:我建议编写一个测试程序来查看 s[] 的值显示什么。您还可以打印出“0123456789”中每个条目的所有值。
我想你很快就会意识到它在做什么,尽管这段代码依赖于 ASCII 编码。
玩得开心!
【讨论】:
你说的是“依赖”——这段代码不能保证在某些 C/C++ 实现中工作吗?在 Java 中,保证'0' == 48
.
C 仍然允许任意字符编码(唯一的限制是数字必须有连续的值,即'1'='0'+1
等),因为祖传的 EBCDIC 废话。任何现代现实世界系统都将使用 ASCII 或 ASCII 超集(最好是 UTF-8,但可能是 ISO-8859-、KOI- 等)以上是关于请解释这段代码在做啥(someChar - 48)的主要内容,如果未能解决你的问题,请参考以下文章