只支持下列转义序列
newline | \n | backslash | \\ |
horizontal tab | \t | question mark | \? |
vertical tab | \v | single quote | \' |
backsapce | \b | double quote | \" |
carriage return | \r | octal number | \ooo |
formfeed | \f | hex number | \xhh |
audible alert | \a |
如果转义其它字符,其行为是未定义的:
If the character following the \ is not one of those specified, the behavior is undefined.
在gcc上测试,实际上是两个独立的字符,但编译器会告警,如"\s"实际上等价于"\\s"。
test.c:5:24: warning: unknown escape sequence: '\s'
8进制转义:
8进制转义是转义字符\后面跟1到3个8进制字符。
转义在第一个非8进制字符或者第3个之后的字符停止。
8进制转义并不需要0开头,任何一个8进制字符0-7开头都可以。
"\0120" 包含2个字符 '\012','0'
"\1a" 包含两个字符 '\1' 'a','\1'的ascii码为1。
'\0'是常用的情况,表示字符NUL。
16进制转义:
16进制转义是\x后面根1个或多个16进制字符,不限制16进制字符的个数,
但是如果最终的值超过了最大字符的范围,则行为是未定义的。
在gcc上测试,16进制转义直到第一个非16进制字符结束,如果范围超过了截取低字节值,并且编译告警:
arning: hex escape sequence out of range
如:unsigned char a[] = "\x1aax";
这里有两个字符(不算结尾\0),等价于
unsigned char [3] = { 0x1aa, 'x', '\0' };
会转义到第一个非16进制字符结束。由于超过了ascii的范围,第一个字符的值实际上等于:
0x1aa & 0xff
如果16进制转义后面想根一个16进制字符,可以拆开字符串,使用C语言的字符串拼接,如:
"\x1aa" "x"
参考:
K&R C
https://stackoverflow.com/questions/45612822/how-to-properly-add-hex-escapes-into-a-string-literal