目录
[1、 引用(掌握)](#1、 引用(掌握))
[1.1 概念](#1.1 概念)
[1.2 引用的性质](#1.2 引用的性质)
[1.3 引用参数](#1.3 引用参数)
[2、 赋值(熟悉)](#2、 赋值(熟悉))
[3、 键盘输入(熟悉)](#3、 键盘输入(熟悉))
[4、 string字符串类(掌握)](#4、 string字符串类(掌握))
[5.1 内联函数(掌握)](#5.1 内联函数(掌握))
[5.2 函数重载 overload(重点)](#5.2 函数重载 overload(重点))
[5.3 哑元函数(熟悉)](#5.3 哑元函数(熟悉))
从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 = a;`
` b = c; // 只是赋值,不是引用,b还是a的引用`
` a = 2;`
` cout << a << " " << &a << endl; // 2 0x61fe88`
` cout << b << " " << &b << endl; // 2 0x61fe88`
` cout << c << " " << &c << endl; // 2 0x61fe88`
` return 0;`
`}`
`
● 声明引用时,必须要初始化
#include <iostream>`
`using namespace std;`
`int main()`
`{`
` int a = 1;`
`// int &b; // 引用必须要初始化`
` cout << a << " " << &a << endl; // 2 0x61fe88`
` return 0;`
`}`
`
● 声明引用时,不能初始化为null
#include <iostream>`
`using namespace std;`
`int main()`
`{`
` int a = 1;`
`// int &b = NULL; // 错误,引用不能初始化null`
`// int &b = nullptr; // 错误,引用不能初始化为nullptr`
` cout << a << " " << &a << endl; // 2 0x61fe88`
` return 0;`
`}`
`
● 声明引用的时候,初始化的值可以是纯数值,但是此时需要使用const关键字修饰,表示该引用为常量引用,这样引用的值不可变。
#include <iostream>`
`using namespace std;`
`int main()`
`{`
` const int &b = 12; // 常量引用`
`// b = 222; // 错误,常量引用的数值不能被改变`
` cout << b << " " << &b << endl;`
` return 0;`
`}`
`
● 可以将变量引用的地址赋值给一个指针,此时指针指向还是原来的变量。
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`int a =` `1;`
`int` `&b = a;`
`int` `*c =` `&b;` `// c同时指向了A和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 =` `2;`
`const` `int` `&b = a;`
`// b = 32; // 错误b是只读的`
` a++;`
` cout << a <<` `" "` `<<` `&a << endl;` `// 3 0x61fe88`
` cout << b <<` `" "` `<<` `&b << endl;` `// 3 0x61fe88`
`return` `0;`
`}`
`
1.3 引用参数
【思考】
写一个函数,函数有两个参数a和b,函数的功能是交换两个传入的参数原来变量的值。
#include <iostream>`
`using namespace std;`
`// 操作的是拷贝的副本,不符合需求`
`void test(int a,int b)`
`{`
` int temp = a;`
` a = b;`
` b = temp;`
` cout << "a =" << a << endl;`
` cout << "b =" << b << endl;`
`}`
`// C语言 再C++中不推荐这样写`
`void test1(int *a, int *b)`
`{`
` *a = *a ^ *b;`
` *b = *a ^ *b;`
` *a = *a ^ *b;`
`}`
`// C++编程方式,符合需求`
`void test2(int &a, int &b)`
`{`
` a = a ^ b;`
` b = a ^ b;`
` a = a ^ b;`
`}`
`int main()`
`{`
` int a1 = 1;`
` int b1 = 2;`
` test2(a1,b1);`
` cout << a1 << endl;`
` cout << b1 << endl;`
` return 0;`
`}`
`
引用作为参数进行定义的时候,在参数传递时,是不会产生副本的,这样会提高运行效率。我们在正常编程当中,建议使用引用进行传递参数。
引用参数,在不参与计算的情况下,我们建议使用const进行修饰,以达到引用的安全性。防止参数在函数内进行不必要的操作,或者是误操作。
2、 赋值(熟悉)
通常编程中使用=进行赋值操作,C++新增了以下赋值语法。
#include <iostream>`
`using namespace std;`
`int main()`
`{`
` int a(10); // 相当于 int a = 10;`
`// a(20); // 只能用于初始化`
` cout << a << endl;`
` int b(a); // int b = a;`
` cout << b << endl;`
` int c(a+b); // int c = a + b;`
` cout << c << endl;`
` return 0;`
`}`
`
在C++11中对上述写法进行了升级。
#include <iostream>`
`using namespace std;`
`int main()`
`{`
` double b = 3.14;`
` int b1 = b;`
` cout << b1 << endl; // 3`
` int b2(b);`
` cout << b2 << endl; // 3`
` int b3{b};`
` cout << b3 << endl; // 3`
` return 0;`
`}`
`
升级:对数据窄化做出警告。
3、 键盘输入(熟悉)
可以使用cin把用户在命令行中的内容赋值到变量中。
cin和cout一样,都属于头文件iostream中的标准输入输出流。
#include <iostream>`
`using namespace std;`
`int main()`
`{`
` int a;`
` // C++的字符串是string`
` string str;`
` cout << "请输入一个数字和字符串" << endl;`
` cin >> a >> str; // 接收键盘输入,一个整数和字符串,可以连续操作`
` cout << a << str << endl;`
` return 0;`
`}`
`
如果cin输入的字符串需要包含空格,则可以使用下面的方式:
#include <iostream>`
`using namespace std;`
`int main()`
`{`
` // C++的字符串是string`
` string str;`
` cout << "请输入字符串,可以包含空格,输入完成后点击回车" << endl;`
` getline(cin,str); // 第二个参数只能是string类型`
` cout << str << endl;`
` return 0;`
`}`
`
4、 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 << endl;`
` cout << str.size() << endl; // 10`
` cout << str.length() << endl; // 10`
` cout << str[1] << endl; // e`
` cout << str.at(1) << endl; // e`
` return 0;`
`}`
`
两种方式都可以,但是在C++当中,更推荐你使用at函数,原因时at函数更安全。但是[ ]的方式效率更高。
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
` string str =` `"helloworld";`
` cout << str[100]` `<< endl;` `// 输出一个越界数据`
` cout << str.at(100)` `<< endl;` `// 会报一个异常,程序运行停止`
` cout <<` `"hello"` `<< endl;`
`return` `0;`
`}`
`
string类支持多种遍历方式
● 普通循环(以for循环为主)
● C++11:for each循环
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
` string str =` `"helloworld";`
`// 以for循环的方式进行输出字符串`
`for(int i =` `0; i < str.length(); i++)`
`{`
` cout << str.at(i);`
`}`
` cout << endl;`
`// 以 for each的方式进行循环遍历字符串`
`for(char i:str)`
`{`
` cout << i;`
`}`
`return` `0;`
`}`
`
字符串与数字转换
#include <iostream>`
`#include <sstream> // 字符串流`
`using namespace std;`
`int main()`
`{`
` string s = "123";`
`// int i = s; 错误`
` // string → int`
` istringstream iss(s);`
` int i;`
` iss >> i;`
` cout << i << endl;` `// 123`
` // int → string`
`// string s2 = i; 错误`
` stringstream ss;`
` ss << i;`
` string s2 = ss.str();`
` cout << s2 << endl;`
` return 0;`
`}`
`
5、函数
5.1 内联函数(掌握)
内联函数用于取代C语言中宏定义的函数,内联函数的正确使用可以提升程序的执行效率。内联函数在编译的时候,直接把函数体展开到主函数中编译,在运行期间可以减少调用的开销。
通常将具有以下性质的函数写为内联函数:
● 代码长度5行以内
● 不包含复杂的控制语句
● 频繁被调用
关键字:inline
#include <iostream>`
`using` `namespace std;`
`// 内联函数`
`inline` `void` `pint_string(string str)`
`{`
` cout << str << endl;`
`}`
`int` `main()`
`{`
`pint_string("hello world");`
`return` `0;`
`}`
`
后续学习的成员函数默认都添加inline修饰。
但是我们手动添加上了inline关键字,将函数声明成内联函数。这个不是我们可以决定的。编译器有自己的判断准则,我们只是给编译器提供一个建议,具体是否为内联函数,还是编译器自己决定的。
5.2 函数重载 overload(重点)
C++中允许多个函数使用同一个名称,这种用法就是函数重载。函数重载要求函数名称相同,但是参数不同(类型、数量、前后顺序不同)。与返回值等其他因素无关。
#include <iostream>`
`using namespace std;`
`void print_show(int i)`
`{`
` cout << "调用了int重载"<< i << endl;`
`}`
`void print_show(float i)`
`{`
` cout << "调用了float重载"<< i << endl;`
`}`
`void print_show(double i)`
`{`
` cout << "调用了double重载"<< i << endl;`
`}`
`void print_show(string str)`
`{`
` cout << "调用了string重载"<< str << endl;`
`}`
`void print_show()`
`{`
` cout << "调用了无参int重载"<< endl;`
`}`
`int main()`
`{`
` print_show(1);`
` return 0;`
`}`
`
5.3 哑元函数(熟悉)
函数的参数只有类型,没有名称,这样参数的就是哑元函数。
#include <iostream>`
`using` `namespace std;`
`// 哑元函数`
`void` `print_show(int)`
`{`
` cout <<` `"调用了int的哑元函数"` `<< endl;`
`}`
`int` `main()`
`{`
`print_show(56);`
`return` `0;`
`}`
`
作用一:哑元函数用来区分函数重载。
作用二:运算符重载中用到。
#include <iostream>`
`using` `namespace std;`
`// 哑元函数`
`void` `print_show(int i,int)`
`{`
` cout <<` `"调用了int的哑元函数"` `<< endl;`
`}`
`void` `print_show(int i)`
`{`
` cout <<` `"调用了int的哑元函数"<< i << endl;`
`}`
`int` `main()`
`{`
`print_show(56,23);`
`return` `0;`
`}`
`