谁能解释一下下面的代码,也请解释一下反斜杠(\
)在这种情况下的作用。\'
, \"
, \ooo
, \ \
,是什么\?
意思?
#include <stdio.h>
int main(){
char a = '\010';
char y = '010';
printf("%d,%d",a,y);
return 0;
}
输出:8,48
这'\010'
是八进制中的八进制转义序列 10
是8
十进制的,它将int
在调用时提升为一个,printf
以便解释该值。
这'010'
是一个多字符常量,它的值是实现定义的,如果我们查看 C99 草案标准部分6.4.4.4
字符常量第10段说(强调我的):
[...]包含多个字符(例如,'ab')或包含不映射到单字节执行字符的字符或转义序列的整数字符常量的值是实现定义的。 [ ...]
如果你正在使用gcc
,你至少会看到这个警告:
警告:多字符字符常量 [-Wmultichar]
并且可能在溢出时也出现此警告:
警告:隐式常量转换溢出 [-Woverflow]
获得的值y
更有趣,因为字符常量有一个整数值,它不能只取第一个字符,多字符常量必须取一个整数值,然后转换为char。clang
有助于提供更详细的警告:
警告:从“int”到“char”的隐式转换将值从 3158320 更改为 48 [-Wconstant-conversion]
和当前版本gcc
产生相同的值,我们可以从这段简单的代码中看到:
printf("%d\n",'010');
那么从哪里来3158320
?gcc
至少,如果我们查看实现定义行为的文档,它会说:
编译器一次计算一个字符的多字符字符常量,将前一个值左移每个目标字符的位数,然后在截断到目标宽度的新字符的位模式中进行或运算特点。最终的位模式被赋予 int 类型,因此是有符号的,无论单个字符是否有符号(与 GCC 3.1 和更早版本略有不同)。如果常量中的字符多于目标 int 中的字符数,编译器会发出警告,并且忽略多余的前导字符。
如果我们执行上面的操作(假设是 8 位字符)文档,我们会看到:
48*2^16 + 49*2^8 + 48 = 3158320
^ ^
| decimal value of ASCII '1'
decimal value of ASCII '0'
gcc
将转换int
为char
使用模数2^8
,无论char
是有符号还是无符号,这实际上给我们留下了最后一位8
或48
.
在第一种情况下,\010
被解释为导致8
.
0
第二种情况,返回(第一个字符)的ascii值010
,即48
.
如果您打开了编译器警告,那么您很可能已经想到了第二个
char y = '010';
自己。(在这种情况下gcc
会发出-Wmultichar
和。)-Woverflow
整数字符常量的类型为
int
。包含映射到单字节执行字符的单个字符的整数字符常量的值是被解释为整数的映射字符表示的数值。包含多个字符(例如'ab'
)或包含不映射到单字节执行字符的字符或转义序列的整数字符常量的值是实现定义的。如果整数字符常量包含单个字符或转义序列,则它的值是当类型char
为单个字符或转义序列的对象的对象转换为 type时产生的值int
。
这是一个转义序列,用于删除某些保留字符的含义,例如'
或指定某些特殊字符,例如换行符'\n'
,或者在这种情况下为具有特定 ASCII 值的字符:
char a = '\010';
定义一个八进制 ASCII 值 10 8的字符,即十进制值 8 10。
char y = '010';
定义一个多字节字符,应该分配给宽字符,而不是char
. 虽然没有定义这个赋值的行为,但在这种情况下,它很可能会导致最后一个字符被存储,在y
希望这可以帮助:
\a Beep
\b Backspace
\f Formfeed
\n New line
\r Carriage return
\t Horizontal tab
\v Vertical tab
\\ Backslash
\' Single quotation mark
\" Double quotation mark
\0 ASCII 0x00 (nul terminator)
\ooo Octal representation
\xdd Hexadecimal representation
\xnn Hexadecimal character code nn
\onn Octal character code nn
\nn Octal character code nn
转义序列是包含反斜杠 (\) 后跟某个字符的字符组合。当您使用几乎所有语言进行编程时,有时您需要参考不会产生特定字符的按键。
例如,假设您开发的语言假定变量用方括号括起来[var]
- 那么如果您输入的值不是变量,那么您将不得不像\[10\]
. 否则你的编译器会认为这10
是一个变量名。
这是一个转义序列 - 请参阅http://en.wikipedia.org/wiki/Escape_sequences_in_C