从C到C++

二、从C到C++

本章介绍一些C++拓展的非面向对象功能。

  1. 引用(掌握)

1.1 概念

引用从一定程度上讲是一个指针的平替,几乎被所有面向对象编程语言所使用。引用相当于对某一个目标变量起"别名"。

操作引用与操作原变量完全一样。

复制代码
#include <iostream>`

`using namespace std;`

`int main()`
`{`
`    int a = 1;`
`    // b是a的引用`
`    int &b = a;`

`    cout << a << " " << &a << endl; //1 0x61fe88`
`    cout << b << " " << &b << endl; //1 0x61fe88`
`    return 0;`
`}`
`

1.2 引用的性质

  • 可以改变引用的值,但是不能再次成为其他变量引用。
复制代码
#include <iostream>`

`using namespace std;`

`int main()`
`{`
`    int a = 1;`
`    // b是a的引用`
`    int &b = a;`
`    int c = 3;`
`    b = c; // 3 只是赋值,不是引用,b还是a的引用`

`    cout << a << " " << &a << endl; //3 0x61fe88`
`    cout << b << " " << &b << endl; //3 0x61fe88`
`    cout << c << " " << &c << endl; //3 0x61fe84`
`    return 0;`
`}`
`
  • 声明引用的时候,必须要初始化。
复制代码
#include <iostream>`

`using namespace std;`

`int main()`
`{`
`    int a = 1;`
`//    int &b; // 错误 引用必须要初始化。`

`    cout << a << " " << &a << endl; //3 0x61fe88`

`    return 0;`
`}`
`
  • 声明引用的时候,不能初始化为null
复制代码
#include <iostream>`

`using namespace std;`

`int main()`
`{`
`    int a = 1;`
`    // int &b = nullptr; // 错误引用不能初始化为null`
`//    int &b = null;`
`    cout << a << " " << &a << endl; //3 0x61fe88`

`    return 0;`
`}`
`
  • 声明引用的时候,初始化的值可以是纯数值,但是此时要用const关键字修饰引用,表示该引用为常量引用,这样引用的值不可变。
复制代码
#include <iostream>`

`using namespace std;`

`int main()`
`{`
`    const int &a = 1;   // 常量引用`
`    // a = 2; // 错误常量引用的数值不能被改变`

`    cout << a << " " << &a << endl; //3 0x61fe88`

`    return 0;`
`}`
`
  • 可以将变量引用的地址赋值 给一个指针,此时指针指向的还是原来的变量。
复制代码
#include <iostream>`

`using namespace std;`

`int main()`
`{`
`    int a = 1;`
`    int &b = a;`
`    int *c = &b;`

`    cout << a << " " << &a << endl; // 1 0x61fe84`
`    cout << b << " " << &b << endl; // 1 0x61fe84`
`    cout << *c << " " << c << endl; // 1 0x61fe84`

`    return 0;`
`}`

`
  • 可以使用const修饰引用,此时如果原变量的值改变了,引用的值也会改变。
复制代码
#include <iostream>`

`using namespace std;`

`int main()`
`{`
`    int a = 1;`
`    const int &b = a;`
`    a++;`
`//    b++;  // 错误的,b是只读的`

`    cout << a << " " << &a << endl; // 2 0x61fe84`
`    cout << b << " " << &b << endl; // 2 0x61fe84`

`    return 0;`
`}`

`

1.3 引用的参数

写一个函数,函数有两个参数a和b,函数 的功能是交换两个传入的参数【原来】变量的值。

复制代码
#include<iostream>`
`#include <string.h>`
`using` `namespace std;`

`// 只是test1内部进行相互交换了`
`// 不符合需求`
`void` `test1(int a,int b)`
`{`
    `int t = a;`
`    a = b;`
`    b = t;`
`}`

`// C语言的指针`
`void` `test2(int` `*a,int` `*b)`
`{`
    `*a =` `*a^*b;`
    `*b =` `*a^*b;`
    `*a =` `*a^*b;`
`}`

`// C++ 编程方式`
`void` `test3(int` `&a,int` `&b)`
`{`
`    a = a^b;`
`    b = a^b;`
`    a = a^b;`
`}`

`int` `main()`
`{`
    `int a =` `1;`
    `int b =` `2;`
    `test3(a,b);`
`    cout << a << endl;`
`    cout << b << endl;`
    `return` `0;`
`}`

`

引用作为参数进行定义的时候,在参数传递时,是不会产生副本的,这样会提高运行效率,我们在正常编程中,建议使用引用作为参数进行传递。

引用参数,在不参与计算的情况,我们建议使用const进行修饰。以达到引用安全的目的。

  1. 赋值(熟悉)

通常编程当中使用=进行赋值操作,C++新增了新的赋值语法。

复制代码
#include<iostream>`
`#include <string.h>`
`using` `namespace std;`


`int` `main()`
`{`
    `int` `a(1);`   `// int a = 1;`
`    cout << a << endl;`
    `int` `b(a);`   `// int b = a;`
`    cout << b << endl;`

    `int` `c(a+b);` `// int c = a + b;`
`    cout << c << endl;`  `// 2`

    `return` `0;`
`}`
`

C++11里对上述写法又进行了升级

复制代码
#include<iostream>`
`#include <string.h>`
`using namespace std;`


`int main()`
`{`
`    double b = 3.14;`
`    int b1 = b;`
`    int b2(b);`
`    int b3{b};  // C++11新增的 对数据窄化做出警告`

`    cout << b1 << endl; // 3 数据窄化`
`    cout << b2 << endl; // 3 数据窄化`
`    cout << b3 << endl; // 3 数据窄化`
`    return 0;`
`}`

`
  1. 键盘输入(掌握)

可以使用cin把用户在命令行中输入的内容赋值到变量中。

cin与cout一样,都属于头文件iostream中标准输入输出流。

复制代码
#include<iostream>`
`#include <string.h>`
`using` `namespace std;`

`int` `main()`
`{`
    `int a;`
    `// C++ 的字符串是string`
`    string str;`

`    cout <<` `"请输入一个数字和字符串:"` `<< endl;`
`    cin >> a >> str ;` `// 接收键盘输入:一个整数和一个字符串,可以连续输入。`
`    cout << a << endl;`
`    cout << str << endl;`

    `return` `0;`
`}`

`
  1. string 字符串类(掌握)

string 不是C++的基本数据类型,他是一个C++标准库中的字符串类,使用时需要引入头文件,#include<string>,而不是string.h

string在绝大多数情况下,可以替代C语言中字符串,不必担心内存是否足够,和字符串长度等,其中内部还包含了很多字符串处理函数,可以完成各种情况下的字符串处理功能。

string和C语言相同,字符串编码使用ASCII编码,不支持中文。

复制代码
#include<iostream>`
`using namespace std;`


`int main()`
`{`
`    string str = "helloworld";`
`    cout << str.size() << endl; // 10字符串长度`
`    cout << str.length() << endl; // 10字符串长度`

`    cout << str[1] << endl; // e`
`    cout << str.at(5) << endl; // w`

`    return 0;`
`}`

`

两种方式都可以,但是在C++中更推荐你使用at函数。原因时at函数更加安全。at函数的运行效率慢。[ ]效率更高。

复制代码
#include<iostream>`
`using namespace std;`


`int main()`
`{`
`    string str = "helloworld";`
`    cout << str.size() << endl; // 10字符串长度`
`    cout << str.length() << endl; // 10字符串长度`

`    // cout << str[100] << endl; // 什么都不输出,也不报错,不安全`
`    cout << str.at(100) << endl; // 安全的,越界会报异常。`

`    return 0;`
`}`
`

string 类支持多种遍历方式

  • 普通循环(for循环)
  • for each循环 C++11
复制代码
#include<iostream>`
`using namespace std;`


`int main()`
`{`
`    string str = "helloworld";`
`    // 以for循环的方式遍历输出字符串`
`    for(int i = 0; i <str.size(); i++)`
`    {`
`        cout << str.at(i);`
`    }`
`    cout << endl;`

`    // for each的方式进行循环遍历字符串`
`    for(char i : str)`
`    {`
`        cout <<i;`
`    }`

`    return 0;`
`}`

`
  1. 函数

5.1 内联函数(掌握)

内联函数用于取代C语言中宏定义的函数。内联函数的正确使用可以提升程序的执行效率。内联函数在编译的时候,直接把函数体展开到主函数中编译,在运行期间可以减少调用的开销。(以空间换时间)

通常将具有以下性质的函数写为内联函数:

  • 代码长度5行以内。
  • 不能包含复杂的控制语句。
  • 被频繁调用
复制代码
#include<iostream>`
`using namespace std;`

`// 声明成-内联函数`
`inline void show(string str)`
`{`
`    cout << str << endl;`
`}`

`int main()`
`{`
`    show("nihao");`
`    return 0;`
`}`

`

内联函数关键字:inline

后续学习的成员函数都默认添加了inline修饰。

但是我们手动添加的inline关键字,将函数声明称内联函数。这个不是我们能决定的。我们只是给编译器提一个建议,编译器有自己的判断准则。具体是否能变成内联函数,还是编译器自己决定的。

5.2 函数重载 overload(重点)

C++中允许多个函数使用同一个名称,这种写法就是函数重载。函数重载要求函数名称相同,但是参数不同(类型或者数量)或者前后顺序不同。与返回值和其他因素无关。

复制代码
#include <iostream>`
`using namespace std;`

`void print_show(int i,double d)`
`{`
`    cout << "调用了int重载" << i << endl;`
`}`

`//void print_show(double d)`
`//{`
`//    cout << "调用了double重载" << d << endl;`
`//}`

`//void print_show(float f)`
`//{`
`//    cout << "调用了float重载" << f << endl;`
`//}`

`void print_show(string str)`
`{`
`    cout << "调用了string重载" << str << endl;`
`}`

`int main()`
`{`
`    print_show(6,5.4);`
`    return 0;`
`}`

`

5.4 哑元函数(熟悉)

函数的参数只有类型,没有名称,有这样的参数的函数就是哑元函数。

复制代码
#include <iostream>`
`using namespace std;`

`// 哑元函数`
`void print_show(int)`
`{`
`    cout << "调用了int重载" << endl;`
`}`


`void print_show(string str)`
`{`
`    cout << "调用了string重载" << str << endl;`
`}`

`int main()`
`{`
`    print_show(6);  // 尽管函数内不用参数,但是还是需要传递参数`
`    return 0;`
`}`
`

作用1:哑元函数用来区分函数重载。

作用2:运算符重载中会用到。

复制代码
#include <iostream>`
`using namespace std;`

`// 哑元函数`
`void print_show(int i,int)`
`{`
`    cout << "调用了int1重载" << endl;`
`}`

`void print_show(int i)`
`{`
`    cout << "调用了int2重载" << endl;`
`}`


`void print_show(string str)`
`{`
`    cout << "调用了string重载" << str << endl;`
`}`

`int main()`
`{`
`    print_show(6,1);  // 尽管函数内不用参数,但是还是需要传递参数`
`    return 0;`
`}`

`
相关推荐
哎呀呀嗯呀呀9 分钟前
class 031 位运算的骚操作
java·算法·位运算
时清云25 分钟前
【算法】合并两个有序链表
前端·算法·面试
瞌睡不来38 分钟前
(刷题记录5)盛最多水的容器
c++·笔记·学习·题目记录
轩辰~42 分钟前
磁盘存储链式结构——B树与B+树
数据结构·b树·算法
何陈陈1 小时前
【Linux】线程池
linux·服务器·开发语言·c++
2401_857297911 小时前
秋招内推2025-招联金融
java·前端·算法·金融·求职招聘
夏旭泽1 小时前
C-include
开发语言·c++
通信仿真实验室1 小时前
MATLAB使用眼图分析QPSK通信系统接收端匹配滤波后的信号
开发语言·算法·matlab
感谢地心引力1 小时前
【Qt】Qt安装(2024-10,QT6.7.3,Windows,Qt Creator 、Visual Studio、Pycharm 示例)
c++·windows·python·qt·visual studio
通信仿真实验室1 小时前
(15)衰落信道模型作用于信号是相乘还是卷积
开发语言·人工智能·算法·matlab