0

我试图测试使用 c-'0' 的 K&R 函数之一。为了清楚地理解,我写了如下两行代码。我的问题是为什么它打印“1”。在这种情况下,“数值”实际上意味着什么。谢谢!

char c = 'a';
printf("%c",c-'0');
4

7 回答 7

8

c - '0'仅当 c 为数字('0'、'1'、... 或 '9')时才具有明确的特定值。

什么时候c'0''0' - '0'0因为它们是相等的,什么时候c'1''1' - '0'1因为在任何 C 实现选择使用的任何字符集中'1'紧随其后。与其他数字'0'相同:值为。'2''9' - '0'9

而且您真的不应该使用"%c"格式说明符打印值。

于 2012-06-19T10:02:24.677 回答
7

数值是字符的 ASCII 值。

'a'是 97,'0'是 48。97-48=49。

49 又是 的值'1',所以这就是打印的内容。

于 2012-06-19T09:59:51.137 回答
6

C 中的字符只不过是一个整数值。它们的值是根据字符编码定义的。ASCII编码非常有名,适用于 OP 发布的问题。因此,'0' 等于 48,'a' 等于 97。通过减去它们,你只是得到了 ASCII 表中这些字符之间的差异。

在这个例子中(相当于你的):

printf("%c",'a'-'0');

你得到1因为 97-48 = 49 对应于 ASCII 字符 '1'。

如果您使用的是(注意“%d”而不是“%c”):

printf("%d",'a'-'0');

那么这将只打印差异(在这种情况下为 49),而不是与差异相关的 ASCII 字符。

于 2012-06-19T10:01:30.947 回答
3

您的代码的行为取决于实现。它依赖于字符的编码。

在我的 Linux 机器上,a字符以ASCII(和 UTF8)编码为单字节97(十进制),即0x61. 同样,0字符被编码为48ie 0x30。不同之'a' - '0'97 - 48在于49恰好是字符的编码1

在一些古老的EBCDIC机器上(例如旧的 IBM 大型机,或者在某种兼容模式或操作系统下运行的新主机),编码是不同的。

使用UTF8(现在经常使用)存在更多字符(例如,ç用于法语拼写的 C cedilla),并且它们通常被编码为一个以上的字节!

于 2012-06-19T10:04:32.493 回答
2

c - '0' 将从 c 中减去 '0'(48) 的字符代码。如果 c 代表一个数字,这将导致对应于 c 的数值(例如 char '3' 为 3)。

为了得到这个数值,你应该在 printf 中使用格式说明符 %d 而不是 %c。

从“a”中减去“0”没有多大意义,但它可能对特定任务有一些应用。

于 2012-06-19T10:01:07.030 回答
1

让我们通过使用整数而不是字符来解释这一点。

char c = 97;
printf("%d", c - 48); 

这当然会打印 49,但是当我们使用 ASCII 表将其转换为字符时,我们得到 1。

char c = 97;
printf("%c", c-48);

此代码现在打印 1,因为我们在打印时使用 char 数据类型,它将 49 值转换为 ASCII 等效数字 1。

为了证明这一点,我们可以尝试这样的事情。

char a = 'a';
char b = 97;
if((a == b) && ((a-'0') == (b-48))) { 
      printf("%s", "true");
}

首先我们看 a 和 b 是否等价,然后我们看 a-'0' 是否与 b-48 等价。因为两者都是真实的,所以我们打印真实。

于 2012-06-19T10:23:09.540 回答
0

单引号内的字符,如 '0',是一个字符常量。它是一个数字常数,取决于机器的字符集。在 ASCII 字符集中,“a”相当于 97,“0”相当于 48。

97-48 = 49,相当于 ASCII 字符集中的 '1'。最后,它将以 %c 格式打印 '1'。

于 2013-12-12T06:30:10.343 回答