【C++ Primer】第3章:字符串、向量和数组

简介: 【C++ Primer】第3章:字符串、向量和数组

第3章 字符串、向量和数组


string表示可变长的字符序列


vector存放的是某种给定类型对象的可变长序列


使用命名空间


using namespace std;


头文件不应包含using声明


1. 标准库类型string


字符串初始化


string s1;
string s2(s1);
string s3("values");     //直接初始化
string s3 = "values";    //拷贝初始化
string s4(n, 'c');      //n个c组成字符串   直接初始化


拷贝初始化和直接初始化


使用等号初始化一个变量叫做拷贝初始化


不使用等号则是直接初始化


string s8 = string(10, 'c');   //拷贝初始化



在执行读写操作时,string对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读写,知道遇见下一个空白为止。


遇到第一个非空白符开始,之后再遇到空白符就结束


例如输入’ Hello World! ‘,会输出’Hello’


int main(){
    string s;
    cin >> s;           //  "  Hello World  "
    cout << s <<endl;   // "Hello"
    return 0;
}


string s1, s2;
cin >> s1 >> s2;             // "  Hello"  " World!"
cout << s1 << s2 <<endl;     //  "HelloWorld!"


一次读入一个单词


int main(){
    string word;
    while(cin >> word){
        cout << word <<endl;
    }
    return 0;
}


一次读入一整行


getline函数的参数是一个输入流和一个string对象。


函数从给定的输入流中读入内容,直到遇到换行符为止(注意换行符也被读进来了),然后把所读的内容存入到那个string对象中去(注意不存放换行符)。


int main(){
    string line;
    while(getline(cin, line)){
        cout << line << endl;
    }
    return 0;
}


string::size_type类型,它是一个无符号类型


auto len = line.size();   //len的类型是string::size_type类型


注意:字符串字面值不能相加,string能相加


切记:字符串字面值与string是不相同的类型



范围for


C++11新标准


for(auto ch : str){
  cout << ch << endl;
}


范围for还可以改变字符串中的字符


string s("Hello World!!!");
for(auto &c : s){
    c = toupper(c);
}
cout << s <<endl;   // "HELLO WORLD!!!"


2. 标准库类型vector


vector是一个类模板


使用模板时,需要指出编译器应把类或函数实例化成何种类型。


不存在包含引用的vector,因为引用非对象。



列表初始化时C++11新标准


vector<string> v{10};       //10个“”
vector<string> v{10, "hi"}  //10个"hi"



迭代器


auto b = v.begin();  //b表示v的第一个元素
auto e = v.end();    //e表示v尾元素的下一个位置     //b,e类型相同


尾后迭代器是容器中不存在的位置


特殊情况下如果容器为空,则begin和end返回的是同一个迭代器


所有标准库容器都可以使用迭代器,只有少数容器支持下标运算符



vector<int>::iterator it;   //能读写
string::iterator it2;       //能读写
vector<int>::const_iterator it3;  //只读不写
string::const_iterator it4;       //只读不写


C++11新标准引入cbegin和cend


auto it3 = v.cbegin();  //it3的类型是vector<int>::const_iterator



迭代器的距离类型:difference_type


用迭代器实现二分查找


auto beg = text.begin(), end = text.end();
auto mid = text.begin + (text.end - text.begin())/2;
while(mid!=end && *mid!=target){
    if(target < * mid){
        end = mid;
    }
    else
        beg = mid + 1;
    mid = beg + (end - beg)/2;
}


3. 数组


数组维度编译的时候已知,是一个常量表达式


默认情况下,数组的元素被默认初始化


不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值


char a1[] = {'C', '+', '+'};       //维度是3
char a2[] = {'C', '+', '+', '\0'}   //维度4
char a3[] = "C++";                 //维度4
const char a4[6] = "Daniel";       //错误,没有空间可存放空字符


从右向左,从内向外


int *ptrs[10];             //ptrs是含有10个整型指针的数组
int &refs[10] = arr;       //错误:不存在引用的数组
int (*Parray)[10] = &arr;  //Parray指向一个含有10个整型的数组
int (&arrRef)[10] = arr;   //arrRef引用一个含有10个整型的数组
int *(&array)[10]  = ptrs;  //array是数组的引用,该数组含有10个指针


使用数组下标的时候,通常将其定义为size_t类型,是无符号整型


指针也是迭代器


c++11新标准引入了begin和end函数


int ia[] = {0,1,2,3,4,5,6,7,8,9};
int *beg = begin(ia);  //指向ia首元素的指针
int *last = end(ia);   //指向arr尾元素的下一个位置的指针


auto n = end(arr) - begin(arr);  //n的值是5,即arr元素个数   是ptrdiff_t类型  距离可能为负,所以是带符号类型


size_t和ptrdiff_t都是定义在cstddef头文件中的机器相关的类型。


C风格字符串


定义在cstring头文件中



与旧代码的接口


不能用string对象直接初始化指向字符的指针,为了完成功能,string专门提供了一个名为c_str的成员函数


char *str = s;  //错误:不能用string对象初始化char*
const char *str = s.c_str();  //正确


不允许用数组初始化数组


不允许用vector对象初始化数组


可以使用数组初始化vector对象


int int_arr[] = {0,1,2,3,4,5};
vector<int> ivec(begin(int_arr), end(int_arr));
vector<int> subVec(int_arr+1, int_arr+4);   //用数组的一部分初始化vector


多维数组


int ia[3][4];
size_t cnt = 0;
for (auto& row : ia) {
  for (auto& col : row) {
    col = cnt;
    ++cnt;
  }
}


for (const auto& row : ia) {   //&不能少
  for (auto col : row) {
    cout << col << endl;
  }
}


指针和多维数组


for(auto p = ia; p != ia + 3; ++p){      //p的类型是指向4个整数的数组的指针
    for(auto q = *p; q != *p +4; ++q){   //q的类型是指向整数的指针
        cout << *q << ' ';
    }
    cout << endl;
}


for(auto p = begin(ia); p != end(ia); ++p){
    for(auto q = begin(*p); q != end(*p); ++q){
        cout << *q << ' ';
    }
    cout << endl;
}


using int_array = int[4];
typedef int int_array[4];    //两句功能一样
for(int_array *p = ia; p != ia + 3; ++p){
    for(int *q = *p; q != *p +4; ++q){
        cout << *q << ' ';
    }
    cout << endl;
}
目录
相关文章
|
4月前
|
搜索推荐 编译器 C语言
【C++核心】特殊的元素集合-数组与字符串详解
这篇文章详细讲解了C++中数组和字符串的基本概念、操作和应用,包括一维数组、二维数组的定义和使用,以及C风格字符串和C++字符串类的对比。
110 4
|
11天前
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
28 5
|
3月前
|
缓存 网络协议 API
C/C++ StringToAddress(字符串转 boost::asio::ip::address)
通过上述步骤和示例代码,你可以轻松地在C++项目中实现从字符串到 `boost::asio::ip::address`的转换,从而充分利用Boost.Asio库进行网络编程。
119 0
|
3月前
|
编译器 C语言 C++
C/C++数字与字符串互相转换
C/C++数字与字符串互相转换
|
4月前
|
C++
C++(十一)对象数组
本文介绍了C++中对象数组的使用方法及其注意事项。通过示例展示了如何定义和初始化对象数组,并解释了栈对象数组与堆对象数组在初始化时的区别。重点强调了构造器设计时应考虑无参构造器的重要性,以及在需要进一步初始化的情况下采用二段式初始化策略的应用场景。
|
4月前
|
C++
HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具
HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具
|
4月前
|
存储 C++
C++(五)String 字符串类
本文档详细介绍了C++中的`string`类,包括定义、初始化、字符串比较及数值与字符串之间的转换方法。`string`类简化了字符串处理,提供了丰富的功能如字符串查找、比较、拼接和替换等。文档通过示例代码展示了如何使用这些功能,并介绍了如何将数值转换为字符串以及反之亦然的方法。此外,还展示了如何使用`string`数组存储和遍历多个字符串。
|
11天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
52 18
|
11天前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
38 13
|
11天前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
37 5