字符序列(Character sequences)

重要的事情说三遍:

强烈建议按照目录结构中的顺序学习!!!点我查看教程目录结构

强烈建议按照目录结构中的顺序学习!!!点我查看教程目录结构

强烈建议按照目录结构中的顺序学习!!!点我查看教程目录结构

string 类在前面的章节中已经简要介绍过。它是一个非常强大的类,用于处理和操作字符字符串。然而,由于字符串实际上是字符序列,我们也可以将它们表示为字符类型元素的普通数组。

例如,以下数组:

char foo [20];

是一个可以存储最多 20 个 char 类型元素的数组。它可以表示为:

c_strings1.jpg

因此,该数组具有存储最多 20 个字符序列的容量。但这种容量不需要完全用尽:数组也可以容纳较短的序列。例如,在程序中的某个时刻,可以在 foo 中存储 "Hello""Merry Christmas" 序列,因为这两个都可以适应容量为 20 个字符的序列。

按照惯例,字符序列中字符串的结束由一个特殊字符标志:空字符(null character),其字面值可以写为 '\0'(反斜杠,零)。

在这种情况下,名为 foo 的 20 个 char 元素的数组可以表示存储字符序列 "Hello""Merry Christmas" 为:

c_strings2.jpg

请注意,在字符串本身的内容之后,添加了一个空字符 '\0' 以指示序列的结束。灰色面板代表具有不确定值的 char 元素。

初始化以空字符结尾的字符序列

由于字符数组是普通数组,它们遵循相同的规则。例如,要用一些预定的字符序列初始化一个字符数组,可以像初始化其他数组一样进行:

char myword[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

上述声明了一个 6 个元素的 char 类型数组,用于初始化形成单词 "Hello" 的字符加上一个空字符 '\0'

但字符元素数组有另一种初始化方式:直接使用字符串字面量。

在前几章的一些示例中已经多次出现了字符串字面量。它们通过将文本用双引号(")括起来来指定。例如:

"the result is: "

这是一个字符串字面量,可能在早期的示例中使用过。

用双引号(")括起来的字符序列是字面常量。它们的类型实际上是以空字符结尾的字符数组。这意味着字符串字面量总是自动在末尾附加一个空字符 '\0'

因此,名为 mywordchar 元素数组可以通过以下两种语句之一用以空字符结尾的字符序列初始化:

char myword[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char myword[] = "Hello";

在这两种情况下,字符数组 myword 都被声明为具有 6 个 char 元素的数组:组成单词 "Hello" 的 5 个字符,加上一个指定序列结束的最后一个空字符 '\0',在第二种情况中,当使用双引号(") 时,它会自动附加。

请注意,这里我们讨论的是在声明时初始化字符数组,而不是稍后分配值(声明后)。实际上,由于字符串字面量是普通数组,它们具有相同的限制,不能分配值。

表达式(如上所述已经声明 myword)如下:

myword = "Bye";
myword[] = "Bye";

无效,就像以下表达式也无效:

myword = { 'B', 'y', 'e', '\0' };

这是因为数组不能被分配值。不过,可以单独为每个元素分配值。例如,这将是正确的:

myword[0] = 'B';
myword[1] = 'y';
myword[2] = 'e';
myword[3] = '\0';

字符串和以空字符结尾的字符序列

普通数组中包含以空字符结尾的字符序列是 C 语言中表示字符串的典型类型(这就是它们也被称为 C 字符串的原因)。在 C++ 中,即使标准库定义了一个特定的字符串类型(类 string),普通数组中包含以空字符结尾的字符序列(C 字符串)仍然是表示字符串的自然方式;实际上,字符串字面量仍然总是产生以空字符结尾的字符序列,而不是 string 对象。

在标准库中,字符串的两种表示方式(C 字符串和库字符串)共存,并且大多数需要字符串的函数都支持两种方式。

例如,cincout 直接支持以空字符结尾的序列,允许它们像字符串一样直接从 cin 中提取或插入到 cout 中。例如:

// 字符串和 NTCS
#include <iostream>
#include <string>
using namespace std;

int main ()
{
  char question1[] = "What is your name? ";
  string question2 = "Where do you live? ";
  char answer1 [80];
  string answer2;
  cout << question1;
  cin >> answer1;
  cout << question2;
  cin >> answer2;
  cout << "Hello, " << answer1;
  cout << " from " << answer2 << "!\n";
  return 0;
}

在这个示例中,同时使用了使用以空字符结尾的字符序列的字符数组和字符串。它们在与 cincout 一起使用时相当可互换,但它们的声明有显著差异:数组具有固定大小,需要在声明时隐式或显式指定;question1 的大小恰好为 20 个字符(包括终止的空字符),而 answer1 的大小为 80 个字符;而字符串只是字符串,没有指定大小。这是因为字符串在运行时具有动态大小,而数组的大小在编译时确定,在程序运行之前。

无论如何,以空字符结尾的字符序列和字符串可以很容易地相互转换:

以空字符结尾的字符序列可以隐式转换为字符串,字符串可以通过使用 string 的成员函数 c_strdata 转换为以空字符结尾的字符序列:

char myntcs[] = "some text";
string mystring = myntcs;  // 将 C 字符串转换为字符串
cout << mystring;          // 以库字符串形式打印
cout << mystring.c_str();  // 以 C 字符串形式打印

(注意:stringc_strdata 成员是等效的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值