C++(string字符串、函数)
4. string 字符串类(掌握)
4.1 基础使用
string不是C++本身的基本数据类型,而是在C++标准库std中的一个字符串类。
在使用时需要引入头文件<string>,而不是<string.h>,string用于在绝大多数情况下代替char*,不必担心内存是否足够、字符串长度等问题。
string内部集成的函数可以完成绝大多数情况下字符串的操作。
string支持多种遍历方式:
- for循环
- for-each循环(C++11)
- 迭代器(后面讲)
#include <iostream>
using namespace std;
int main()
{
string s = "fsdhfjdhsjkf";
// size和length效果完全相同
cout << "字符串长度:" << s.size()
<< " " << s.length() << endl;
cout << "for循环遍历:" << endl;
for(int i = 0;i<s.size();i++)
{
cout << s[i] << " ";
}
cout << endl << "for-each遍历:" << endl;
for(char i:s)
cout << i << " ";
return 0;
}
4.2 取出元素
在C++中除了使用[]取出元素外,还可以使用at函数取出元素。
在绝大多数情况下,更推荐使用at函数取出元素,因为at函数更安全,但是[]性能更好。
#include <iostream>
using namespace std;
int main()
{
string s = "fsdhfjdhsjkf";
cout << s[1] << endl; // 's'
// at函数
cout << s.at(1) << endl; // 's'
// cout << s[-100] << endl; // '\0'或乱码
cout << s.at(-100) << endl; // 检测到越界则终止运行
cout << "主函数结束" << endl;
return 0;
}
4.3 字符串与数字转换
转换方式有很多种,在此使用的是字符串流。
整数 → 字符串
#include <iostream>
#include <sstream> // 头文件
using namespace std;
int main()
{
int i = 2323;
stringstream ss;
ss << i;
string s = ss.str();
cout << s << endl;
return 0;
}
字符串 → 整数
#include <iostream>
#include <sstream> // 头文件
using namespace std;
int main()
{
string s = "12345";
istringstream iss(s);
int i;
iss >> i;
cout << i << endl;
return 0;
}
5. 函数
5.1 内联函数 inline(掌握)
在C++中使用内联函数主要是为了取代C语言中宏定义的函数,内联函数在编译时,可以直接展开函数体到主函数中,因此提升了程序执行的效率,消除了普通的额外开销。
建议把代码长度较小(1-5行且不能包含复杂的控制语句)且频繁使用的函数定义为内联函数,内联函数只是给编译器的建议,编译器并不一定采纳。
只要在函数定义处使用inline关键字修饰函数,就可以把函数设置为内联函数。
#include <iostream>
using namespace std;
/**
* @brief test 内联函数
*/
inline void test(int a)
{
cout << "fdfd" << endl;
cout << ++a << endl;
}
void func(); // 函数声明
inline void func() // 函数定义
{
cout << "翻江倒海发的" << endl;
cout << "法国活动经费" << endl;
}
int main()
{
int a = 1;
test(a);
func();
return 0;
}
需要注意的是,后面要学习的成员函数默认都定义为内联函数。
5.2 函数重载 overload(掌握)
C++中允许同一个函数名称定义多个函数,这就是函数重载。
函数签名是编译器区分不同函数的方式,包括以下几个组成部分:
- 函数名称
- 参数数量
- 参数类型
两个函数的签名不可以相同,即一个函数只有一个独一无二的签名。
当函数签名中函数名称相同,剩余条件不同时(参数数量或参数类型不同),就构成了函数重载。
#include <iostream>
using namespace std;
void test()
{
cout << "没有参数" << endl;
}
void test(int a)
{
cout << "一个int参数" << a << endl;
}
void test(int a,int b)
{
cout << "两个int参数" << a+b << endl;
}
void test(string a,string b)
{
cout << "两个string参数" << a+b << endl;
}
//int test(string a,string b) 错误
//{
// cout << "两个string参数" << a+b << endl;
// return 1;
//}
int main()
{
test(1,3);
test(54);
test();
test("aa","bb");
return 0;
}
后面学习的函数中,需要注意的是:构造函数可以重载,但是析构函数不能重载。
5.3 函数的参数默认(缺省)值(掌握)
C++允许给函数的参数设定默认值,调用函数时如果传入参数,传入的参数会覆盖默认值;调用时如果不传递参数,参数使用预设的默认值。
函数的参数默认值既可以在声明处(建议)设定,又可以在定义处设定,但是只能出现一次。
向右(后)原则:如果函数的参数有多个,只要某个参数设定了默认值,其右边(后面)的所有参数都要设定默认值。
#include <iostream>
using namespace std;
void func(int a = 1)
{
cout << a << endl;
}
void test(int a = 2);
void test(int a)
{
cout << a << endl;
}
void method(int a,int b = 1,int c = 2)
{
cout << a << b << c << endl;
}
int main()
{
func(); // 1
func(2); // 2
test(); // 2
test(1); // 1
method(6); // 612
method(6,6); // 662
method(6,6,6); // 666
return 0;
}
尽量不要同时使用函数重载和参数默认值,因为非常容易出现二义性问题。
#include <iostream>
using namespace std;
void method(int a,int b = 1,int c = 2)
{
cout << "A" << a << b << c << endl;
}
void method(int a)
{
cout << "B" << a << endl;
}
int main()
{
method(8,8,8); // A888
method(5,5); // A552
// method(9); 错误
return 0;
}
5.4 哑元函数(熟悉)
一个函数的参数只有类型没有名字,这个参数就是哑元。包含哑元的函数就是哑元函数。
#include <iostream>
using namespace std;
void test(int)
{
cout << "AAA" << endl;
}
int main()
{
// test(); 错误
test(34897);
return 0;
}
哑元函数的实际功能包括但不限于:
- 在C++的运算符重载中区分重载函数(后面讲)。
- 保持函数的向前兼容性。
......
这篇笔记承接上一篇笔记。
最后,给大家留两个练习题来检验一下最近的学习情况。(答案明天晚上在下一篇笔记更新)
练习:
1.键盘输入一个100-999之间的数,依次输出这个数的个十百位。
2.输入一行字符串,分别统计出其中的英文字母、数字和其他字符的个数。