飞道的博客

[C++]string、vector和数组

287人阅读  评论(0)

string

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


  
  1. #include <string>
  2. 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:


  
  1. int main()
  2. {
  3. string st("a");
  4. cout << st.size() <<  endl;
  5. return  0;
  6. }

这里打印的结果是1。

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


  
  1. int main()
  2. {
  3. string s("Hello World");
  4. for ( auto a : s) {
  5. cout << a <<  endl;
  6.     }
  7. return  0;
  8. }

也可以修改字符:


  
  1. int main()
  2. {
  3. string s("Hello World");
  4. for ( auto &a : s) {
  5. a =  toupper(a);
  6.     }
  7. cout << s <<  endl;
  8. return  0;
  9. }

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

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


  
  1. int main()
  2. {
  3. string s("Hello World");
  4. for ( auto i =  0; i <= s.size(); i++) {
  5. s[i] =  toupper(s[i]);
  6.     }
  7. cout << s <<  endl;
  8. return  0;
  9. }

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

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

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

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


  
  1. int main()
  2. {
  3. int i =  42;
  4.      // converts the int i to its character representation
  5. string s = to_string(i);
  6. return 0;
  7. }

vector

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


  
  1. #include <vector>
  2. 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的示例:


  
  1. int main()
  2. {
  3.      // list initialization, articles has 3 elements
  4. vector< string> articles = { "a""an""the"};
  5. vector< string> svec;  // default initialization has no elements
  6. vector< int> ivec; // ivec holds objects of type int
  7. vector<Sales_item> Sales_vec;  // holds Sales_items
  8. vector< vector< string>> file;   // vector whose elements are vectors
  9. vector< vector< int>> vecOfvec;  // each element is itself a vector
  10.      // all five vectors have size 0
  11. cout << svec.size() <<  " " << ivec.size() <<  " "
  12. << Sales_vec.size() <<  " "
  13. << file.size() <<  " " << vecOfvec.size() <<  endl;
  14. vector<intivec2(10);      // ten elements, each initialized to 0
  15. vector<intivec3(10-1)// ten int elements, each initialized to -1
  16. vector<stringsvec2(10);   // ten elements, each an empty string
  17. vector<stringsvec3(10"hi!")// ten strings; each element is "hi!"
  18. cout << ivec2.size() <<  " " << ivec3.size() <<  " "
  19. << svec2.size() <<  " " << svec3.size() <<  endl;
  20.      // 10 is not a string, so cannot be list initialization
  21. vector<stringv1(10)// construct v1 with ten value-initialized elements
  22. vector< string> v2{ 10};  // ten elements value-initialized elements
  23. vector<stringv3(10"hi");   // ten elements with value "hi"
  24.      // again list initialization is not viable, so ordinary construction
  25. vector< string> v4{ 10"hi"};   // ten elements with values "hi"
  26.      // all four vectors have size ten
  27. cout << v1.size() <<  " " << v2.size()
  28. <<  " " << v3.size() <<  " " << v4.size() <<  endl;
  29. vector< string> vs1{ "hi"};  // list initialization: vs1 has 1 element
  30. vector< string> vs2{ 10};    // ten default-initialized elements
  31. vector< string> vs3{ 10"hi"};  // has ten elements with value "hi"
  32. cout << vs1.size() <<  " " << vs2.size() <<  " " << vs3.size() <<  endl;
  33. vector<intv5(101);   // ten elements with value 1
  34. vector< int> v6{ 101};   // two elements with values 10 and 1
  35. cout << v5.size() <<  " " << v6.size() <<  endl;
  36.      // intention is clearer
  37. vector< int> alt_v3 = { 10};     // one element with value 10
  38. vector< int> alt_v4 = { 101};  // two elements with values 10 and 1
  39. cout << alt_v3.size() <<  " " << alt_v4.size() <<  endl;
  40. for ( auto a : alt_v4) {
  41. cout << a <<  endl;
  42.     }
  43. for ( auto i =  0; i < alt_v4.size(); i++) {
  44. cout << alt_v4[i] <<  endl;
  45.     }
  46. return  0;
  47. }

这里需要主要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的值,它是带符号整型数。

关于迭代器的示例:


  
  1. int main()
  2. {
  3. string s("Hello World");
  4. for ( auto iter = s.begin(); iter != s.end(); iter++) {
  5. *iter =  toupper(*iter);
  6.     }
  7. cout << s <<  endl;
  8. return  0;
  9. }

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

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

数组

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

关于数组遍历的示例:


  
  1. int main()
  2. {
  3. int a[] = { 1234};
  4. int *pb =  std::begin(a);
  5. int *pe =  std::end(a);
  6. for (; pb != pe; pb++) {
  7. cout << *pb <<  endl;
  8.     }
  9. return  0;
  10. }

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


转载:https://blog.csdn.net/jiangwei0512/article/details/116465445
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场