为什么'\97';ascii值等于55

为什么'\97';ascii值等于55,c,ascii,C,Ascii,就像C代码一样: #包括 内部主(空){ 字符c='\97'; printf(“%d”,c); 返回0; } 结果是55,但我不知道如何计算它。 我知道八进制数或十六进制数跟在“\”后面,97是十六进制数吗?\是一个八进制转义序列,但9不是有效的八进制数字,因此它被解释为一个多字符常量a\9和一个1,其值由实现定义。在没有任何警告标志的情况下,gcc默认提供以下警告: warning: unknown escape sequence: '\9' [enabled by default] war

就像C代码一样:

#包括
内部主(空){
字符c='\97';
printf(“%d”,c);
返回0;
}
结果是
55
,但我不知道如何计算它。
我知道八进制数或十六进制数跟在“\”后面,
97
是十六进制数吗?

\
是一个八进制转义序列,但
9
不是有效的八进制数字,因此它被解释为一个多字符常量a
\9
和一个
1
,其值由实现定义。在没有任何警告标志的情况下,
gcc
默认提供以下警告:

warning: unknown escape sequence: '\9' [enabled by default]
warning: multi-character character constant [-Wmultichar]
warning: overflow in implicit constant conversion [-Woverflow]
C99标准草案第6.4.4.4节字符常量第10段(重点部分)中规定:

整型字符常量的类型为int。整型字符常量的值 包含映射到单字节执行字符的单个字符是 被解释为整数的映射字符表示形式的数值。 包含多个字符的整数字符常量的值(例如。, “ab”),或包含不映射到单个字节的字符或转义序列 执行字符,是实现定义的

例如,
gcc
实现被记录如下:

编译器每次计算一个字符的多字符字符常量,将前一个值按每个目标字符的位数进行移位,然后将新字符的位模式截断为目标字符的宽度。最后的位模式是int类型,因此是有符号的,不管单个字符是否有符号(与GCC的3.1和更早版本相比有一点变化)。如果常量中的字符数超过目标int中的字符数,编译器将发出警告,多余的前导字符将被忽略

例如,对于具有8位字符的目标,“ab”将被解释为“(int)((无符号字符)“a”*256+(无符号字符)“b”),而“\234a”将被解释为“(int)((无符号字符)“\234”*256+(无符号字符)“a”)

据我所知,这被解释为:

char c = ((unsigned char)'\71')*256 + '7' ;
这导致
55
,这与上面的多字符常量实现一致,尽管
\9
\71
的转换不明显

编辑

后来我意识到真正发生的是
\
正在被删除,因此
\9->9
,所以我们真正拥有的是:

c = ((unsigned char)'9')*256 + '7' ;
这似乎更合理,但仍然武断,我不清楚为什么这不是一个直截了当的错误

更新

<> P>从注释的C++参考手册中我们发现,在经典的C和旧版本的C++中,当反斜杠跟随字符不是定义为一个SCAPE序列时,它等于字符的数值。手臂部分
2.5.2

这与经典C和早期版本C++的解释不同,其中,黑素字序列的后继字符字符集中的字符的值,如果不定义为转义序列,等于字符的数值。例如“\q”将等于“q”


\9
不是有效的转义序列,因此它很可能返回到普通的
9
字符

这意味着它与
'97'
相同,它是未定义的实现定义(参见Shafik Yaghmour的回答)行为(2个字符不能容纳1个字符…)



为了避免将来出现这种情况,请考虑在编译器上启动警告。例如,

gcc
的最小值应为
-Wall-Wextra-pedantic

\9不是有效的转义,因此编译器忽略它,ascii“7”为55

我不会依赖于这种行为,它可能是未定义的。但那就是55号的来源


编辑:Shafik指出它不是未定义的,它是实现定义的。参考资料请参见他的答案。

首先,我假设您的代码应该阅读此内容,因为它与您的标题匹配

#include<stdio.h>
int main(void) {
  char c = '\97';
  printf("%d",c);
  return 0;
}
#包括
内部主(空){
字符c='\97';
printf(“%d”,c);
返回0;
}
\9
无效,因此我们假设字符实际上是7
7
是ascii 55,这是打印出来的答案


我不知道你想要什么,但这不是…

@ShafikYaghmour啊。我很久没有使用默认的编译器设置了,所以我不知道。如果是这样的话,OP应该已经看到了警告,并且能够从中找到答案/
#include<stdio.h>
int main(void) {
  char c = '\97';
  printf("%d",c);
  return 0;
}