理解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
字符编码为48
即0x30
。 差异'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”。