跳至主要內容

Different

LincZero大约 5 分钟

Different

目录

字符类型

字符

  • C语言:单引号声明字符、双引号声明字符串
  • Python:单引号或双引号声明字符串,没有字符类型

转义字符

转义字符与字面量(多语言)

字符名称C/C++JavaHTML英语ASCII符号十进制ASCII码十六进制ASCII码
换行符\n\nline feedNL(LF)100x0A
水平制表符\t\ttableHT90x09
垂直制表符\vverticalVY110x0B
退格\b\bbackspaceBS80x08
回车\rcarriage returnCR130x0D
振铃\aalertBEL70x07
反斜杠\\\920x5C
单引号\'\''390x27
双引号\"\""quotes"340x22
问号\?\??630x3F
换页符\f
空字符\0
空格毋需\s space
与号毋需毋需&&
小于号毋需毋需&lt;less<
大于号毋需毋需&gt;greater than>
八进制ASCII\0dd\ddd
16进制ASCII\0xaa
16进制Unicdoe\uxxxx\uxxxx

补充:

  • 现代系统并非都支持所有的转义序列。例如输入振铃字符时,有些系统保持沉默
  • 通用字符名:\u后8个十六进制位,\U后16个十六进制位,表示的是ISO 10646码点

字符串拼接

  • C语言:需要引入库<string.h>,再用函数strcat(str1,str2)
  • Python、Java:使用字面量表达方式+

底层实现

  • C/C++、Qt:不自带,分别使用string.h、string、QString库,底层由数组实现

    • 元素是可变的(本质就是修改数组元素)
  • Java:使用String

    • 元素是不可变的(本质上是指针,但Java不能直接通过指针操作地址)

    • Java这样做的原因:

      • Java字符串由char值序列组成,而他的char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元。

        length方法将返回采用UTF-16编码表示的给定字符串所需要的代码单元数量

        s.charAt(n)方法返回序列为n的代码单元

        如果能够修改序列成员,其代码单元的长度是不可控的(大多数的常用Unicode字符是一个代码单元,有一些会超出)

  • Python:Python自带

    • 元素是不可变的(不是指针,可以通过==直接比较字符串大小)
    • Python这样做的原因:
      • (1) 字符串能更好地作为字典的主键
      • (2) 好像是对于变量的底层存储模型不同???????

原理互通

C字符数组 vs JavaString

在C程序员第一次接触Java字符串的时候,常常会感到迷惑,因为他们总将字符串认为是字符型数组

char greeting[] = "Hello";

这种认识是错误的,Java字符串大致类似于char*指针

char* greeting = "Hello";

替换字符时的原理

char* temp = malloc(6);
strncpy(temp, greeting, 3);
strncpy(temp+3, "p!", 3);
greeting = temp;

是否会内存泄露:不会,Java会自动进行垃圾回收。如果一块内存不再使用了,系统最终会将其回收。

greeting = "Howdy";

C++ String对象 vs JavaString

  • 也自动地进行内存的分配与回收。内存管理是通过构造器、赋值操作和析构器显式执行的。
  • 然而,C++字符串是可修改的,也就是说,可以修改字符串中的单个字符。

比较

  • C

    • 不能用~~==~~,比较的是地址。本质上都是指针。strcmp()
  • C++ String类

    • C++的string类重载了==运算符以便检测字符串内容的相等性
    • 可惜Java没有采用这种方式,它的字符串 “看起来、感觉起来” 与数值一样,但进行相等性测试时,其操作方式又类似于指针 语言的设计者本应该像对+那样也进行特殊处理,即重定义==运算符。
  • Java

    • 不能用~~==~~,比较的是地址。本质上都是指针。s.equals(t)

    • 但和C/C++不同的是,Java中的字符串是共享的

      如果虚拟机始终将相同的字符串共享,就可以使用==运算符检测是否相等。

      但实际上只有字符串常量是共享的,而+或substring等操作产生的结果并不是共享的。

      String greeting = "Hello";
      if(greeting == "Hello");				// probably true
      if(greeting.substring(0,3) == "Hel");	// probably false    
      
  • Python

    • ==:使用来比较两个字符串内的value值是否相同
    • is:比较两个字符串的id值

特殊字符串(格式、原始、模板字符串)

语言

格式字符串

  • 原始字符串
  • 模板字符串
  • 拼接字符串

c/c++

格式字符串

printf("Hello, %s! Your age is %d.\n", name, age);

原始字符串

不支持

模板字符串

不支持

字符串拼接(这个有点怪)

// 字符串字面值可以通过相邻放置在一起实现拼接
const char* str = "Hello, " "world" "!";

python

格式字符串

'%s, %s' % (name1, name2) 						# 旧版格式字符串。Hello, world
'{mame1}, {name2}'.format(name1, name2=name2)	# 新版格式字符串。Hello, world

原始字符串

r'Hello, \nworld!'	# 也能用大写的R

模板字符串

f'{hello}, {world}'	# Python中也叫字符串插值

# 但实际上,python的“模板字符串”不是上面那个,而是这个
from string import Template
t = Template("Hello, $name! Your age is $age.")
print(t.substitute(name=name, age=age))

字符串拼接

combined_str = "Hello, " + "world!"

js

格式字符串

console.log("Hello, %s! Your age is %d.", name, age);

原始字符串

不支持

模板字符串

console.log(`Hello, ${name}! Your age is ${age}.`)

字符串拼接

var combined_str = "Hello, " + "world!";

java

格式字符串

System.out.printf("Hello, %s! Your age is %d.\n", name, age);

原始字符串

String rawString = `Hello, \nworld!` // Java12+支持

模板字符串

不支持

字符串拼接

+