《C和C++代码精粹》——2.9 字符串数组

简介:

本节书摘来自异步社区出版社《C和C++代码精粹》一书中的第2章,第2.9节,作者: 【美】Chuck Allison,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.9 字符串数组

C和C++代码精粹
有两种方式来描述C风格的字符串数组:(1)指针数组;(2)二维数组。程序清单2.13中的程序说明了第一种方式。内存分布如下:
image

程序清单2.13 用指向字符的指针数组来实现字符串

// array6.cpp:粗糙的数组  
#include <iostream>  
#include <cstring>  
using namespace std;  

main()  
{  
    char*  strings[] = {"now","is","the","time"};  
    size_t n = sizeof strings / sizeof strings[0];  

    //从粗糙的数组打印  
    for (int i = 0; i < n; ++i)  
        cout << "String " << i  <<" == \"" << strings[i]  
             << "\",\tsize == " << sizeof strings[i]  
             << ",\tlength == " << strlen(strings[i])  
             << endl;  
}  

//输出:  
String 0 == "now",   size == 4,   length == 3  
String 1 == "is",    size == 4,   length == 2  
String 2 == "the",   size == 4,   length == 3  
String 3 == "time",  size == 4,   length == 4

由于字符串可以有不同的长度,所以这一类型的数组有时被称为粗糙的(ragged)数组。这一方式仅使用了容纳数据所需的内存数量,再加上指向每个字符串的指针。运行时系统传递给main函数的命令行参数数组argv是一个粗糙的数组。

粗糙的数组方式的一个不利之处是,在大多数环境中,需要动态地为每个字符串分配内存(参见第20章)。如果你不介意浪费一小部分空间,而且如果你也知道会遇到的最长的字符串的长度,就可以使用一个固定大小的区域来存储二维字符数组(每行一个字符串)。程序清单2.14中数组的内存区域分布如下:

image

程序清单2.14 作为二维字符数组中的行来实现字符串

// array7.cpp: 在二维字符数组中存储字符串  
#include <iostream>  
#include <cstring>  
using namespace std;  

main()  
{  
    char array[][5] = {"now","is","the","time"};  
    size_t n = sizeof array / sizeof array[0];  

    for (int i = 0; i < n; ++i)  
        cout << "array[" << i << "] == \"" << array[i]  
             << "\",\tsize == " << sizeof array[i]  
             << ",\tlength == " << strlen(array[i])  
             << endl;  
}  

//输出:  
array[0] == "now",   size == 5,   length == 3  
array[1] == "is",    size == 5,   length == 2  
array[2] == "the",   size == 5,   length == 3  
array[3] == "time",  size == 5,   length == 4

正如这个程序所表明的,如果多维数组的第一维能从它的初始化中推断出来,那么就不必具体指出多维数组的第一维。

在程序设计语言中C++在某种程度上是独一无二的,因为在使用数组时仅可以使用其部分下标。就像程序清单2.14中的程序所使用的那样,表达式array[i]是指向第i行的指针。对于一个定义为int a2[4]的数组,a[i]代表的是什么呢?而ai又是什么呢?请继续读下一节。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
23天前
|
自然语言处理 算法 前端开发
C++与Doxygen:精通代码文档化之道
C++与Doxygen:精通代码文档化之道
48 0
|
25天前
|
存储 算法 编译器
【C++ 字符数组的模板特化】面向字符串的C++模板特化:理解与实践
【C++ 字符数组的模板特化】面向字符串的C++模板特化:理解与实践
47 1
|
1月前
|
自然语言处理 安全 C++
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
76 1
|
1月前
|
存储 缓存 安全
C++数组全解析:从基础知识到高级应用,领略数组的魅力与技巧
C++数组全解析:从基础知识到高级应用,领略数组的魅力与技巧
52 1
|
24天前
|
Linux 编译器 程序员
【Linux 调试秘籍】深入探索 C++:运行时获取堆栈信息和源代码行数的终极指南
【Linux 调试秘籍】深入探索 C++:运行时获取堆栈信息和源代码行数的终极指南
65 0
|
29天前
|
IDE Linux 开发工具
内存泄漏检测工具Valgrind:C++代码问题检测的利器(一)
内存泄漏检测工具Valgrind:C++代码问题检测的利器
65 0
存储 编译器 Linux
18 0
|
3天前
|
安全 C++
石头剪子布(字符串解法 C++)
石头剪子布(字符串解法 C++)
15 0
|
17天前
|
C语言 C++ 容器
C调用C++代码
C调用C++代码
12 1
|
23天前
|
算法 程序员 C语言
C++设计哲学:构建高效和灵活代码的艺术
C++设计哲学:构建高效和灵活代码的艺术
60 1