1 / 73

C++ 程序设计

C++ 程序设计. string 、 vector. 3.1 标准库 string 类型. 3.1.1 对象与变量. 一般情况下,为了与内置类型变量相区别,称复杂数据类型的变量为 对象 ( object ),或称某某数据类型对象。 广义讲, 常量、变量 都称为 对象 ,狭义讲,对象仅指 复杂数据类型的变量 ,在本书中,沿用对象广义概念, 类变量 称为对象, 基本数据类型 的变量称为对象, 常量 也称为对象。. 3.1.2 string 对象的定义和初始化. 为了在程序中使用 string 类型,必须包含 string 头文件 ,并导入名字空间,如下:

karlyn
Télécharger la présentation

C++ 程序设计

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C++程序设计 string、vector

  2. 3.1 标准库string类型 3.1.1 对象与变量 一般情况下,为了与内置类型变量相区别,称复杂数据类型的变量为对象(object),或称某某数据类型对象。 广义讲,常量、变量都称为对象,狭义讲,对象仅指复杂数据类型的变量,在本书中,沿用对象广义概念,类变量称为对象,基本数据类型的变量称为对象,常量也称为对象。

  3. 3.1.2 string对象的定义和初始化 为了在程序中使用string类型,必须包含string头文件,并导入名字空间,如下: #include <string> using std::string; 标准库string是类类型,类类型对象通过构造函数初始化,构造函数是一个特殊的类成员函数,在类对象初始化的时候执行。

  4. 3.1.2 string对象的定义和初始化 表3-1 string的几个常用构造函数

  5. 3.1.3 string对象的输入输出 【例 3.1】string对象的输入和输出操作。 #include <iostream> #include <string> using namespace std; // using std::string; int main( ) { string s1, s2;// 定义s1、s2,并初始化s1、s2为空字符串 // 依次读取字符串一赋给s1,字符串二赋给s2 cin >> s1 >> s2; // 注意空白字符s1="hello world" cout << s1 << s2 << endl; // 输出s1和s2 return 0; } 提示:利用 getline(cin,s1)可实现整行字符的读取

  6. 3.1.4 string对象的操作 对象成员包括该数据类型定义的成员函数和内部数据成员,要调用一个对象的成员函数,或者引用一个对象的内部数据成员,通过“.”运算符,表示如下: 对象名.数据成员 或者 对象名.成员函数名(参数表) 前者引用的是数据成员,后者调用成员函数,这里,“.”是一个运算符,功能是表示对象的成员。

  7. 3.1.4 string对象的操作 1.string的大小和容量函数 • 一个C++字符串存在3种大小,相应的函数分别是: • 函数size( )和length( )等价,都返回string对象中字符个数。函数empty( )判断字符串是否为空,判断字符串是否空也可以利用函数size( )或者length( ),将长度与0比较;

  8. 3.1.4 string对象的操作 【例 3.2】string的大小和容量函数的使用。 #include <iostream> #include <string> using namespace std; int main( ) { string s("Hello World!"); // s初始化为"Hello World!" cout << s.length( ) << endl; cout << s.size( ) << endl; if ( s.empty( ) ) cout << "s 是空串" << endl; else cout << "s 长度是" << s.size( ) << endl; return 0; }

  9. 3.1.4 string对象的操作 2.string关系运算 string类定义了常见的关系运算符(==、!=、<、<=、>、>=),关系运算符比较两个string对象时采用大小写敏感的字典序策略。 • str1、str2比较,不失一般性,假设str1.length()< str2.length(),str2比str1长,如果str1与str2前面部分相同,则 str1小于str2。 • 如果str1和str2的字符不同,则比较第一个不匹配的字符。

  10. 3.1.4 string对象的操作 例如: string subStr = "Hello"; string phrase = "Hello World"; string str = "Hi"; 如果两两比较,则subStr小于phrase,str大于subStr,str大于phrase。

  11. 3.1.4 string对象的操作 string类还支持比较成员函数compare( ),compare( )支持用索引值和长度定位子串来进行比较,返回一个整数,如: string s("abcd"); string s2("ab"); s.compare("abcd"); // 将s("abcd")和"abcd"比较,相等,返回0 s.compare("dcba"); // 将s("abcd")和"dcba"比较,返回一个小于0的值 s.compare( s2 );// 将s("abcd")和s2("ab")比较,返回大于0的值 s.compare(s);// 相等,返回0 //将s(“abcd”)中“ab”和s(“abcd”)中“cd”比较,返回值小于0

  12. 3.1.4 string对象的操作 3.string对象的赋值 string对象的赋值可使用操作符运算符=,如: string strTo, strFrom=“hello”; strTo = strFrom;

  13. 3.1.4 string对象的操作 4.string对象相加 相加指字符串连接,支持string对象和string对象、string对象与const char*对象、string对象与char对象,可以通过使用加运算符(+)或复合赋值运算符(+=)连接,结果生成一个新的string对象,例如 string s1("Hello "); string s2("World\n"); 下面通过加法生成新的string对象: string s3 = s1 + s2; // s3是:Hello World\n string + string // s4是:Hello Kitty string + 字符串字面值 string s4 = s1 + "Kitty";

  14. 3.1.4 string对象的操作 如果要把s2直接追加到s1末尾,可以使用+=运算符: s1 += s2; // 相当于s1 = s1 + s2 string加法返回的是string对象,和流输入输出(>>、<<)返回流对象类似,可以串接使用,如下: string s1, s2; cin >> s1 >> s2; s1 = s1 + ", " + s2;// 注意+ 左操作数必须是string对象 // s1="error"+","+s2 cout << s1 << ", " << s2 << endl;

  15. 3.1.4 string对象的操作 5.string对象的字符元素存取 string类型支持通过下标运算符[ ]或者通过at( )函数访问其中的字符元素,下标运算符[ ]需要一个size_type类型的值,作为“下标”或“索引”,以标明要访问字符的位置,string对象的下标从0开始,如果s是一个string对象且s不空,则s[0]就是字符串的第一个字符,s[1]就表示第二个字符,而s[s.size( )-1]则表示s的最后一个字符。

  16. 3.1.4 string对象的操作 【例 3.12】string对象的字符元素存取操作。 #include <iostream> #include <string> using namespace std; int main( ) { string s("some string"); for (string::size_type ix = 0; ix != s.size( ); ++ix) { cout << s[ix] << endl; } for (string::size_type index = 0; index != s.size( ); ++index) { cout << s.at(index) << endl; } return 0; }

  17. 3.2 标准库vector类型 vector称为容器,因为vector能够像容器一样存放各种数据类型的对象,不过,同一个vector中的所有对象都必须是相同数据类型,格式是将数据类型放在vector后面的尖括号中,例如: vector<int> ivec; // ivec可存取int类型的元素 vector<string> svec; // svec可存取string类型元素

  18. 3.2.1 vector对象的定义和初始化 为了在程序中使用vector类型,必须包含vector头文件,并导入名字空间,如下: #include <vector> using std::vector; vector<int> ivec; 如果不导入名字空间,则需要通过域限定符::引用vector: std::vector<int> ivec;

  19. 3.2.1 vector对象的定义和初始化 表3-3 vector类型的几个常用构造函数

  20. 3.2.1 vector对象的定义和初始化 • vector<T> v1 • 创建一个T类型的空的vector对象。 • vector<T> v2(v1) • 用vector对象v1初始化对象v2时,v2中每一个元素都初始化为v1中相应元素的副本,v1和v2必须同元素类型。 • vector<int> ivec1; // ivec1可存放int类型的元素 • vector<int> ivec2(ivec1);// 通过从ivec1复制元素来创建ivec2 • vector<string> svec(ivec1);// 错误:svec的元素类型是string

  21. 3.2.1 vector对象的定义和初始化 • vector<T> v3(n, i) • 用元素个数和元素值初始化vector对象。 vector<int> ivec4(10, -1); 创建一个包含10个int类型数据的vector,每个元素都初始化为-1; vector<string> svec(10, "hi!"); 创建一个包含10个string类型数据的vector,每个元素都初始化为"hi!"。

  22. 3.2.1 vector对象的定义和初始化 • vector<T> v4(n) 创建一个包含n个T类型数据的vector对象,vector中元素的初始化,取决于vector中存储的元素的数据类型,如果vector保存基本数据类型的元素(如int、float),则用0初始化每个元素。 vector<float> fvec(10); // 10个元素,初始化为0 如果vector保存的是含有构造函数的类类型的元素(string),则用该类型的缺省构造函数初始化每个元素: vector<string> svec(10); // 10 个元素,初始化为空字符串

  23. 3.2.2 vector对象的操作 表3-4 常用的vector操作

  24. 3.2.2 vector对象的操作 vector的大小和容量函数 vector的empty( )和size( )函数与string类似,size( )返回vector相应的size_type类型,注意,使用size_type类型时,必须同时包含vector的元素类型: vector::size_type // 错误 vector<int>::size_type // 正确

  25. 3.2.2 vector对象的操作 2.向vector中添加元素 push_back( )函数将一个新元素添加到vector对象的后面,也就是“尾插”。 // 从标准输入读入单词并存储到vector中 #include <vector> using std::vector; string word; vector<string> svec; // 空vector for (int i = 0; i < 10; i++) { cin >> word; svec.push_back(word); // word尾插到svec中 }

  26. 3.2.2 vector对象的操作 3.vector的下标操作 vector支持通过下标运算符[ ]或者通过at( )函数访问元素,索引的数据类型是vector<T>::size_type,下标从0开始,如果ivec是一个vector<int>对象且ivec不空,则ivec[0]就是ivec的第一个字符,ivec[1]表示第二个字符,ivec[ivec.size( )-1]表示ivec的最后一个元素。 vector的at( )函数会检查索引参数的范围,如果索引无效,会抛出out_of_range异常。

  27. 3.2.2 vector对象的操作 【例 3.4】vector的操作示例一。 #include <iostream> #include <vector> using namespace std; int main( ) { vector<int> ivec; // 空vector // 索引数据类型是vector<T>::size_type,这里是vector<int>::size_type for (vector<int>::size_type index = 0; index < 7; ++ index) { ivec.push_back(index) ; // 尾插 } cout<<ivec.size()<<endl; for (vector<int>::size_type idx = 0; idx != ivec.size( ); ++idx) { cout << ivec[idx] << ", "; // 下标运算符[ ] } cout << endl; for(unsigned i=0;i<ivec.size();i++){ ivec.pop_back(); // 删除最后一个数据元素 } cout<<ivec.size()<<endl; cout << endl; return 0;} 运行结果: 7 0, 1, 2, 3, 4, 5, 6, 0

  28. 3.2.2 vector对象的操作 4.下标操作不添加元素 下标只能索引已存在的元素,必须是已存在的元素才能用下标运算符进行索引,试图索引不存在的元素将产生运行时错误,例如: vector<int> ivec; // 空vector cout << ivec[0]; // 错误:ivec中尚没有元素 vector<int> ivec2(10); // ivec2包含10个元素 // 错误:索引越界,ivec元素的索引范围:0…9 cout << ivec[10];

  29. 3.2.2 vector对象的操作 因为不能索引尚不存在的元素,所以,不能通过vector的下标赋值添加元素,如下: vector<int> ivec; // 空vector for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec[ix] = ix + 3; // 应用程序错误 ivec是空的vector对象,添加元素正确写法应该是: vector<int> ivec; // 空vector for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec.push_back( ix + 3 ); // 尾插

  30. 3.2.2 vector对象的操作 5.删除vector中的元素 vector提供了erase( )、pop_back( )删除vector中的元素,pop_back( )功能是删除vector中最后一个元素,如果vector为空,则相当于什么也没做。

  31. 3.2.2 vector对象的操作 【例 3.14】vector的操作示例二。 #include <iostream> #include <vector> using namespace std; int main( ) { vector<int> ivec; vector<int>::size_type ix; for (ix = 0; ix != 10; ++ix) ivec.push_back( ix + 1 ); // 填充ivec for (ix = 0; ix != ivec.size( ); ++ix) cout << ivec.at(ix) << ", "; // 输出ivec cout << endl; ivec.pop_back( ); // ivec.pop_back( )

  32. 3.2.2 vector对象的操作 for (ix = 0; ix != ivec.size( ); ++ix) cout << ivec.at(ix) << ", "; cout << endl; vector<int>::iterator beg = ivec.begin( ); ivec.erase(beg + 4); // erase( pos ) for (ix = 0; ix != ivec.size( ); ++ix) cout << ivec.at(ix) << ", "; cout << endl; beg = ivec.begin( ); vector<int>::iterator end = ivec.end( ); ivec.erase(beg + 3, end - 2); // erase(beg, end) for (ix = 0; ix != ivec.size( ); ++ix) cout << ivec.at(ix) << ", "; cout << endl; return 0; } 运行结果: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 6, 7, 8, 9, 1, 2, 3, 8, 9,

  33. 3.3 数组 数组的作用 程序设计中,在处理相互间有关联的变量(如数列、矩阵等)时,通过数组把多个相同类型的变量有序地组织起来,可以提高编程效率,改善代码的可读性 。

  34. 3.3.1 数组的定义 数组定义的一般形式为: 类型说明符 数组名 [常量表达式], …; 类型说明符可以是除引用类型外的任意数据类型,数组名是标识符,方括号中的常量表达式是数组元素个数,称为数组的长度,例如: int A[5]; // 定义int类型数组A,有5个元素 // 定义float类型数组B和C,长度分别为10和20 float B[10], C[20]; char ch[20]; // 定义char类型数组ch,有20个元素

  35. 3.3.1 数组的定义 不能用变量定义元素的个数,数组要求在定义时有确定的数据类型和长度,以便分配存储空间,例如: #define FD 5 int main( ) { int A[3 + 2], B[7 + FD]; …} 是合法的, 下述数组定义是错误的: int main( ) { int n = 5; int A[n]; // 错误:定义时,数组长度不可以是变量 …}

  36. 3.3.2 数组的初始化 数组的初始化是在定义数组的同时,为其元素提供一组用逗号分隔的初值,初值用花括号{ }括起来,称为初始化列表。 const unsigned array_size = 5; int ia[array_size] = {0, 1, 2, 3, 4}; 初始化赋值的一般形式为: 类型说明符 数组名[常量表达式] = {值,值,…值} 当{ }中值的个数少于元素个数时,只给前面部分元素赋值,例如: int a[10] = {0, 1, 2, 3, 4};

  37. 3.3.2 数组的初始化 另外,只能给元素逐个提供初值,例如:给5个元素全部赋初值1,只能写为: int a[5] = {1, 1, 1, 1, 1 }; 而不能写为: int a[5] = 1; 给全部元素赋值,则在数组定义中,可以不给出数组元素的个数,例如: int a[5] = {1, 2, 3, 4, 5}; 可写为: int a[ ] = {1, 2, 3, 4, 5}; // 编译器自动确定数组长度5 因为显式初始化,编译器会根据列出的元素个数确定数组长度。

  38. 3.3.2 数组的初始化 在数组定义时,如果没有指定数组元素的初值,则数组元素的初始化规则如下:基本数据类型数组,如果在函数体外定义,则其元素均初始化为0,如果在函数体内定义,则其元素不初始化。 int A[5]; // 基本数据类型数组 float B[10], C[20]; // 遵循变量初始化规则

  39. 3.3.3 字符数组 字符数组是指数组元素是字符的一类数组,可以用来存放多个字符,也可用来存放字符串。可以用一组由花括号括起来、逗号隔开的字符字面值进行初始化,也可以用一个字符串字面值进行初始化。字符串字面值包含一个额外的空字符(‘\0’),标志字符串结束。 当使用字符串字面值来初始化创建的新字符数组时,将在新数组中加入空字符。 char ca1[] = {‘C’, ‘+’, ‘+’}; // 未追加空字符 char ca2[] = {'C', '+', '+', '\0'}; // 显式追加空字符'\0' // 用字符串字面值初始化的数组,其末位包含'\0' char ca3[] = "C++";

  40. 3.3.3 字符数组 例如,下面的初始化式将出现编译时的错误: char ca4[5] = "Hello" ; // 错误:数组ca4有6个元素

  41. 3.3.4 数组元素的访问 与vector不同,一个数组不能用另外一个数组初始化,也不能将一个数组直接赋值给另一个数组: int ia[] = {0, 1, 2, 3}; int ia2[4]; int ia4[](ia); // 错误:数组不能用另外一个数组初始化 ia2 = ia; // 错误:不能将数组赋值给另外一个数组 数组元素用下标运算符[ ]来访问,数组元素也是从0开始计数。

  42. 3.3.4 数组元素的访问 【例 3.6】数组元素的复制与输出。 #include <iostream> using namespace std; int main( ) { int ia[] = {0, 1, 2, 3, 4}; int ia2[5]; for(size_t ix = 0; ix < 5; ix++) { ia2[ix] = ia[ix];// 通过循环,对数组元素逐个复制 } for(size_t index = 0; index < 5; index++) { // 通过循环,对数组元素逐个输出 cout << ia2[index] << “, ”; } cout << endl; return 0; } 运行结果: 0, 1, 2, 3, 4,

  43. 3.3.5 二维数组与多维数组 C++语言支持多维数组,多维数组的元素有多个下标。 • 二维数组的定义 二维数组是一个m行n列矩阵,二维数组定义的一般形式是: 类型说明符 数组名[<m>][ <n>], …; 其中:m、n是常量表达式,m为数组行数,n为数组列数,分别是数组第1维和第2维的长度,例如 int a[3][4]; 二维数组元素的访问形式为: 数组名[下标1][下标2], 例如:a[1][2]表示数组a的第2行3列的元素。

  44. 3.3.5 二维数组与多维数组 • 二维数组初始化 • 二维数组可以看作元素是一维数组的数组,即其每一个元素是一个一维数组,二维数组初始化的方法有: • 给所有元素赋初值。给数组的所有元素赋初值的方法有两种,方法一: • {{0行初值}, {1行初值}, …, {m行初值}} • 即每行一个花括号,花括号间用逗号分隔,全部初值再用一个花括号,例如: • int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };

  45. 3.3.5 二维数组与多维数组 方法二: {0行初值, 1行初值, …, m行初值} 所有初值放在一个花括号中,按数组排列的顺序给各元素赋初值,例如: int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 注意:若对所有元素都赋初值,则定义数组时行数可不指定,而列数必须指定,例如: int a[ ][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; 或: int a[ ][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

  46. 3.3.5 二维数组与多维数组 • 部分元素赋初值 {{0行部分初值}, {1行部分初值}, …, {m行部分初值} } 例如: int a[3][4] = {{1, 2}, {5}, {9, 10, 11} };

  47. 3.3.5 二维数组与多维数组 • 二维数组的应用 【例 3.7】5个学生,3门课程,学号及成绩如表3-5所示,编程求每个学生的平均成绩,并输出每个学生的学号、3门课程成绩和平均成绩。

  48. 3.3.5 二维数组与多维数组 #include <iostream> using namespace std; int main( ) { int A[5]; // 存储学号 float S[5][4]; //存储5个学生3门课成绩和平均成绩 int i, j; for (i = 0; i < 5; i++) { cin >> A[i]; // 输入5个学生的学号 for (j = 0; j < 3; j++) cin >> S[i][j]; // 输入3门课成绩 } for (i = 0; i < 5; i++) { // 计算每个学生的平均成绩 S[i][3] = (S[i][0] + S[i][1] + S[i][2]) / 3; }

  49. 3.3.5 二维数组与多维数组 for (i = 0; i < 5; i++) { cout<< A[i] << " "; // 输出学号 // 输出每个学生的3门课程成绩和平均成绩 for (j = 0; j < 4; j++) cout << S[i][j] << " "; cout << endl; } return 0; }

  50. 3.4 指针 在C++中,将系统为变量、数组、函数等分配的内存首地址称为指针,C++支持通过指针操纵内存单元,在程序中,用一个变量来存放指针,存放指针的变量称为指针变量,在不引起混淆的时候,将指针变量简称指针,将内存首地址简称为内存地址或者地址。

More Related