博客
关于我
[C++]string、vector和数组
阅读量:500 次
发布时间:2019-03-06

本文共 5149 字,大约阅读时间需要 17 分钟。

string

需要注意,为了跟C语言兼容,字符串字面值与string是不同的类型。要使用string,先包含如下的内容:

#include 
using std::string;

初始化string的方式:

如果不赋值,就得到空字符。如果使用“=”就是拷贝初始化,否则就是直接初始化。像S4那样的操作,只能使用直接初始化;而S2和S3则直接初始化和拷贝初始化都可以使用。

string操作:

使用cin输入到string对象,会自动忽略开头的空白,值到遇到下一个空白为止,其间的内容才会被放到string对象中,也即是string对象中不会有空白字符。如果想要保留输入的空白字符,可以使用getline()函数,它会将换行符之前的所有内容都放到string对象,注意不包含换行符本身。当然,两者遇到EOF(按Ctrl+z再按Enter)都会退出。

size()返回的类型是string::size_type,它是无符号类型,且足够放下任何string对象的大小。注意size()的返回没有包含字符串最后的空字符(其实是没有空字符),所以"a"这个字符串的size()返回值是1:

int main(){    string st("a");    cout << st.size() << endl;    return 0;}

这里打印的结果是1。

string对象中的字符可以单独修改。可以通过for来遍历字符:

int main(){    string s("Hello World");    for (auto a : s) {        cout << a << endl;    }    return 0;}

也可以修改字符:

int main(){    string s("Hello World");    for (auto &a : s) {        a = toupper(a);    }    cout << s << endl;    return 0;}

这里将string对象中的字符都转换成了大写。需要注意跟上一个例子的差异,这里for循环中使用了引用而不是新的变量,否则修改没有意义。

string对象也可以通过[]用下标访问:

int main(){    string s("Hello World");    for (auto i = 0; i <= s.size(); i++) {        s[i] = toupper(s[i]);    }    cout << s << endl;    return 0;}

像toupper这样的函数,在C语言也有相同功能和名称的函数,在C++中也可以使用,如下:

还有对C风格字符串的操作(位于<cstring>):

上述函数不能作用于string对象。注意C风格字符串其实是数组,且以空字符结束。C++中最好不要使用它们。

从内置类型转到string可以使用to_string()函数:

int main(){    int i = 42;    // converts the int i to its character representation    string s = to_string(i);    return 0;}

vector

vector表示对象的集合,包含的对象类型需要是相同的,但是不能包括引用(因为引用不是对象)。vector是容器的一种,后面还会介绍其它容器。要使用vector,先包含如下的内容:

#include 
using std::vector;

vector的初始化:

如果未初始化,得到的是空的vector。=是拷贝初始化。如果提供初始元素值,则使用“{}”来初始化。注意跟使用“()”的差别,它是指n个val来初始化vector,val可以是默认值,有对象T本身的类型决定默认值是什么。“{}”可以做“()”能做的初始化,而反过来则不行。

vector的操作:

size()返回的值不是vector::size_type,而是vector<T>::size_type,T是具体的类型,比如int。通过下标可以索引vector,但是不能添加元素,添加元素使用push_back()。

vector的示例:

int main(){    // list initialization, articles has 3 elements    vector
 articles = {"a", "an", "the"}; vector
 svec; // default initialization has no elements vector
 ivec; // ivec holds objects of type int vector
 Sales_vec; // holds Sales_items vector
> file;  // vector whose elements are vectors vector
> vecOfvec; // each element is itself a vector    // all five vectors have size 0 cout << svec.size() << " " << ivec.size() << " " << Sales_vec.size() << " " << file.size() << " " << vecOfvec.size() << endl; vector
 ivec2(10);     // ten elements, each initialized to 0 vector
 ivec3(10, -1); // ten int elements, each initialized to -1 vector
 svec2(10);  // ten elements, each an empty string vector
 svec3(10, "hi!"); // ten strings; each element is "hi!" cout << ivec2.size() << " " << ivec3.size() << " " << svec2.size() << " " << svec3.size() << endl;    // 10 is not a string, so cannot be list initialization vector
 v1(10); // construct v1 with ten value-initialized elements vector
 v2{10}; // ten elements value-initialized elements vector
 v3(10, "hi");  // ten elements with value "hi"    // again list initialization is not viable, so ordinary construction vector
 v4{10, "hi"};  // ten elements with values "hi"    // all four vectors have size ten cout << v1.size() << " " << v2.size() << " " << v3.size() << " " << v4.size() << endl; vector
 vs1{"hi"}; // list initialization: vs1 has 1 element vector
 vs2{10};   // ten default-initialized elements vector
 vs3{10, "hi"}; // has ten elements with value "hi" cout << vs1.size() << " " << vs2.size() << " " << vs3.size() << endl; vector
 v5(10, 1);  // ten elements with value 1 vector
 v6{10, 1};  // two elements with values 10 and 1 cout << v5.size() << " " << v6.size() << endl;    // intention is clearer vector
 alt_v3 = {10};    // one element with value 10 vector
 alt_v4 = {10, 1}; // two elements with values 10 and 1 cout << alt_v3.size() << " " << alt_v4.size() << endl; for (auto a : alt_v4) { cout << a << endl;    } for (auto i = 0; i < alt_v4.size(); i++) { cout << alt_v4[i] << endl;    } return 0;}

这里需要主要v2和v4,它们都使用了“{}”,但是因为成员是string,所以10不会被解释成string,而是解释成了个数,所以v2是10个空字符串的vector,跟v1一致;v4是包含10个"hi"的vector,跟v3一致。

迭代器

前面使用了for、下标等方式访问string和vector,还可以使用迭代器来遍历string和vector。迭代器跟指针类似,就是通过从头到尾访问元素的方式完成遍历。string和vector,以及后面会介绍的容器,都支持迭代器,它们拥有begin()和end()两个成员用于返回迭代器,前者指向开头,后者指向尾后,即最后一个元素的下一个(不存在的)元素。如果迭代器类型对象本身为空,则begi和end返回的都是尾后。

标准容器迭代器的操作:

而string和vector支持的更多:

n是一个整型数值,但是两个迭代器相减,得到的是类型为difference_type的值,它是带符号整型数。

关于迭代器的示例:

int main(){    string s("Hello World");    for (auto iter = s.begin(); iter != s.end(); iter++) {        *iter = toupper(*iter);    }    cout << s << endl;    return 0;}

对于迭代器的类型,一般直接就写auto了,让编译器来决定。不过实际上我们还是可以确定其类型的,比如上面的示例中,iter的类型是string::iterator。begin()和end()返回的迭代器可用于修改值,因为*iter是引用,但是如果想要返回的迭代器只用于读操作,则可以使用其const版本:cbegin()和cend(),它返回的是const_iterator。

vector可以通过push_back()插入元素,此时原本的迭代器就失效了,这需要注意。

数组

数组跟C语言中的没有太大区别。C++中增加了迭代器给数组用,使用begin()和end()函数(它们属于std),并返回成员的指针,也就是说指针成了迭代器,可以使用迭代器的运算操作。两个指针相减得到的是类型为ptrdiff_t的值。在C++中编译器在使用数组的时候会把它转换成指针。

关于数组遍历的示例:

int main(){    int a[] = {1, 2, 3, 4};    int *pb = std::begin(a);    int *pe = std::end(a);    for (; pb != pe; pb++) {        cout << *pb << endl;    }    return 0;}

返回的指针也是一个指向数组开头,一个指向数组尾后。

转载地址:http://lkodz.baihongyu.com/

你可能感兴趣的文章
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询数据库所有表的字段信息
查看>>
【Java基础】什么是面向对象?
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>
mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
查看>>
mysql 死锁(先delete 后insert)日志分析
查看>>
MySQL 死锁了,怎么办?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>