理解c-‘0’

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

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

c - '0'只有一个确定的特定值,当c是一个数字(’0’,’1’,…或’9’)时。

c'0''0' - '0'0因为当c'1'时它们相等, '1' - '0'1因为'1' '0'在任何字符集中紧跟'0' C实现选择使用。 '2'和其他数字相同: '9' - '0'的值为9

你真的不应该用"%c"格式说明符打印一个值。

数值是字符的ASCII值。

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

49,反过来,是'1'的值,所以这是打印的。

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字符。

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

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

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

使用UTF8 (现在经常使用)存在更多字符(例如法语拼写的Ccedillaç),它们通常以多个字节编码!

c – ‘0’将从c中减去’0’(48)的字符代码。 如果c表示数字,则这将导致对应于c的数值(例如,对于char’3’为3)。

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

从’a’中减去’0’没有多大意义,但也许它会有一些特定任务的应用。

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

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

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

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

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

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

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

首先,我们看看a和b是否相等,然后我们看看a-‘0’是否等同于b-48。 由于两者都是真的,我们打印为true。

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

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