申请内存空间: new 类型名 [size], 申请可以存 size 个该数据类型对象的存储空间
释放内存空间: delete 指针名;
像这样:
- int * p; // 声明 int 类型指针
- p = new int[5]; // 申请 5 个 int 类型数据的存储空间
- cout <<p << endl; // 该内存空间的首地址
- delete p; // 释放内存空间
4. 引用
为现有对象起个别名, 别名代表的内存空间与引用对象的内存空间是一样的
引用的声明方式: 数据类型 (类型名) & 别名 = 对象名;
& 的位置无关紧要
像这样:
- int c = 10;
- int & d = c;
- int& e = c;
- int &f = c;
- cout << c << endl;
- cout << d << endl;
- cout << e << endl;
cout << f << endl;
我们再进一步的使用它
- int a = 5; // 定义 int 类型变量, 并赋值
- cout << a << endl; // 输出变量 a 的值: 5
- cout << &a << endl; // 输出变量 a 的地址: 0x7ffeefbff52c
- int & b = a;
- cout << b << endl; // 引用 b 的值: 5
- cout << &b << endl; // 引用 b 的地址: 0x7ffeefbff52c
可以看到, 上下两组输出结果是一样的, 也就是说引用 b, 和变量 a 都是代表的同一块内存地址
所以更改 b 的值, a 的值也会变
- b = 8;
- cout << a << endl;
注意: 引用, 就是给一块已经存在的内存添加一个新的标识符, 所以使用引用没有分配新的内存空间, 所以可以通过引用来修改原来的对象, 但是不能有空引用, 它必须和一声正确的存储区域关联
像这样: 是错误的
int & b; // 编译器提示信息: Declaration of reference variable 'b' requires an initializer, 变量 b 需要一个初始化器
引用的作用
a. 引用用于函数的参数表, 不产生临时对象, 提高安全性和执行效率
- void swap(int & a, int & b) {
- int temp = a;
- a = b;
- b = temp;
- }
- int a = 5;
- int b = 10;
- cout << "交换前" << "a 的值:" << a << "b 的值:" << b << endl;
- swap(a, b);
- cout << "交换后" << "a 的值:" << a << "b 的值:" << b << endl;
b. 引用用于函数返回值 用到的时候很少, 因为不安全, 你可能问访问到一个已经被释放的对象
引用可以这么使用
- int a = 5;
- int & b = a; // 声明引用
- int * p = &a; // 声明指向变量的指针
- int * q = &b; // 声明指向引用的指针
- int * & r = p; // 声明指针对指针的引用 (p, r 是指针, 等号左边 * 代表声明的 r 是指针, & 代表声明的 r 是引用)
但是不能这么使用
int & & s = a; // 不能声明引用的引用
指针和引用的区别和联系
联系: 它们都会对内存地址上存在的变量进行修改, 但引用不占用新的地址, 节省开销
区别: 指针是低级的直接操作内存地址的机制, 可由整型数强制类型转换得到, 功能强大, 但是容易出错, 引用是较高级的封装了指针的特性, 不直接操作内存地址, 不可强制类型转换得到, 安全性高
5. 对指针使用 const 限定符
a. 指向常量的指针
- int a = 5;
- int b = 8;
- const int * p = &a; // 指向常量的指针, 也就是 "*p=" 不成立, 也就是不能通过指针 p 修改指向的内存地址中的值, 但是 p 的值可以更改
- *p = 10; // 错误
- p = &b; // 正确
b. 常量指针
- int a = 5;
- int b = 8;
- int * const p = &a; // 常量指针, 也就是 "p=" 不成立, 也就是 p 的值不能更改, 但是是它所指向的内存地址中的值可以修改
- *p = 10; // 正确
- p = &b; // 错误
c. 指向常量的常量指针
- int a = 5;
- int b = 8;
- const int * const p = &a; // 指向常量的的常量指针, 既不可以通过 p 修改它所指向的内存地址中的值, 也不可更改 p 的值
- *p = 10; // 错误
- p = &b; // 错误
6. 泛型算法应用于普通数组
- // 定义数组
- int a[] = {3, 2, 1, 5, 4};
- int b[5] = {};
- // 数组反转
- // reverse(a, a + 5);
- // 升幂排序
- // sort(a, a + 5);
- // 降幂排序
- // sort (a, a+5, greater<int>());
- // 复制数组内容
- // copy(a, a + 5, b);
- // 逆向复制数组 a 中的内容到数组 b
- // reverse_copy(a, a + 5, b);
- // 检索
- // int * p = find(a, a + 5, 5);
- // cout <<p << endl;
- // cout << a + 5 << endl;
- // if (p == a + 5) {
- // cout << "没有值为 5 的数组元素" << endl;
- // } else {
- // cout << "有值为 5 的数组元素" << endl;
- // }
- // 正向输出
- copy(a, a + 5, ostream_iterator<int>(cout, "数字"));
- cout <<endl;
- // 逆向输出
- reverse_copy(a, a + 5, ostream_iterator<int>(cout, "数字"));
- for (int i = 0; i < 5; i++) {
- cout << a[i] << " ";
- }
- cout << endl;
- for (int i = 0; i < 5; i++) {
- cout << b[i] << " ";
- }
cout << endl;
7. 程序的编辑, 编译, 连接, 运行的基本概念
使用编辑器编辑一个 C++ 源程序, 也就是源文件, 扩展名为. cpp, 像这样: Hello.cpp;
使用 C++ 编译器对这个源程序进行编译, 产生目标文件, 扩展名为. obj, 像这样: Hello.obj;
使用连接程序, 将目标文件与系统库连接, 产生可执行文件, 扩展名为. exe, 你这样: Hello.exe
任何时候我们都不要忘记语言只是我们解决问题的工具, 思想才是我们解决问题的本质, 技术不深, 我们可以去查, 去练习, 而思想只有慢慢的去陪养, 去思考, 去总结!
来源: https://juejin.im/post/5c2da39a51882538472099ef