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.输入一行字符串,分别统计出其中的英文字母、数字和其他字符的个数。

相关推荐
浪里个浪的10241 分钟前
【C语言】计算3x3矩阵每行的最大值并存入第四列
c语言·开发语言·矩阵
Tmbcan1 分钟前
zkw 线段树-原理及其扩展
数据结构·zkw 线段树
@东辰8 分钟前
【golang-技巧】-自定义k8s-operator-by kubebuilder
开发语言·golang·kubernetes
2301_801760939 分钟前
数据结构--PriorityQueue
数据结构
乐悠小码15 分钟前
数据结构------队列(Java语言描述)
java·开发语言·数据结构·链表·队列
史努比.16 分钟前
Pod控制器
java·开发语言
敲敲敲-敲代码25 分钟前
游戏设计:推箱子【easyx图形界面/c语言】
c语言·开发语言·游戏
ROC_bird..34 分钟前
STL - vector的使用和模拟实现
开发语言·c++
机器视觉知识推荐、就业指导34 分钟前
C++中的栈(Stack)和堆(Heap)
c++
MavenTalk40 分钟前
Move开发语言在区块链的开发与应用
开发语言·python·rust·区块链·solidity·move