单个字符(一般被''包围)和单个字符的字符串(一般被'包围)看起来很像,实则可能天差地别。脚本语言可以把任何字面量看成字符串,它的处理更简单优雅,对于编译型语言,程序员必然要面对差异。
字符类型用什么形式表示?
字符类型和普通整型、标识符不同,它必须用特别的形式以区分开。
- 单引号
- C/ObjC/C++/Java/C#/仓颉/Pascal 等
例如'ab'是不合法的。
- C/ObjC/C++/Java/C#/仓颉/Pascal 等
- 单引号或者双引号
- Python/Shell/SQL/JS/PHP/Fortran 等
字符和字符串单引号还是双引号?
- C/C++ 字符是char类型,用单引号,本质就是整型,字符串是双引号。单个字符的字符串代表指针或者地址,指向此字符串。
- Java/C# 字符串也是双引号,只是字符串被当成引用类型(本质还是地址)。
- Python对于单引号'和双引号"包裹的字符看成一样,被当做字符串处理。
- Shell脚本单引号和双引号都代表字符串,但单引号会完全当原本的字符串,双引号内部的变量和命令会被展开。
- SQL语言不区分单引号和双引号。
- JavaScript对于字符串类型,不区分单引号和双引号。
- PHP默认可以用双引号或单引号包裹字符串,为了方便,双引号里面包含单引号字符不需要转义;单引号包裹字符串,内部的任何字符原文输出,注意,内部字符串还包含单引号就必须转义。
- 仓颉字符串是双引号。
- 更为古老的Fortran语言,字符串用单引号和双引号包起来是相同含义,字符类型其实是字符串长度为1的实现:CHARACTER(LEN=1).
- character(2) :: str = "ab"和character(2) :: str = 'ab'都代表字符串ab.
Fortran还可以用nHxxxx格式表达字符串,例如str = 6HHello代表字符串"Hello".
- character(2) :: str = "ab"和character(2) :: str = 'ab'都代表字符串ab.
- Kotlin 单引号表示字符,双引号表示字符串。
- VB用双引号表示字符串。
- Pascal 字符串也是用单引号,不能用双引号。
多行字符串
为了更方便表达多行字符串,不少编程语言提供了形如三引号或者原始字符串标志。
- 仓颉提供3个双引号开头和结尾的设计。
- PHP 4引入了<<<多行字符串。
字符的输出形式
- C/ObjC/C++可以用字符也可以用整数展示,分别对应%c, %d.
'a'和"a"的区别
- 在单引号表示字符,双引号标识字符串的语言中,二者是截然不同的类型。
- 假设语言兼容ASCII码,C/ObjC/C++ 'a'仅仅是单字节字符,"a"包含字符'a'和'\0'两个字符。
- 对于单引号和双引号功能一样的语言,二者没区别。
- C语言 printf('a') 的结果是未知的,因为'a'是个整数,而非字符串地址。
多个字符的字符类型
- 早期一些C语言编译器允许形如 '123' 这种的字符定义,实际上的数值可能是第一个字符,或者最后一个字符。但这些都不重要,不要试图在当今的C编译器写上面的代码。
- 以clang 14为例,它同样支持:char c = 'ab'; 不过有警告:multi-character character constant [-Wmultichar],implicit conversion from 'int' to 'char' changes value from 24930 to 98.
结果是c等于最后一个字符'b'的数值:98.
当然,这种写法并不推荐。
- 以clang 14为例,它同样支持:char c = 'ab'; 不过有警告:multi-character character constant [-Wmultichar],implicit conversion from 'int' to 'char' changes value from 24930 to 98.
字符串换行
一般而言,一个字符串字面量需要在同一行,不能断然换行,原因有二。
- 简化编译器设计,不需要处理换行后还是字符串的延续。
- 换行的字符串可能误导程序员,以为字符串真的有换行。
C/ObjC/C++/Kotlin 等语言均遵循此原则。