零蚀
指针基础
-
指针申明&初始化
int *point=0; int *point=NULL; int *point= nullptr; // c++ 推荐方式 int *point= &x;
- 指针和别名的区别
int &a=c; // 申明一个引用,指向一个int类型的数据 int *b=c; // 申明一个指针,指向一个int数据
- 指针解引用
int *p=&a; *p=a; // int *p等同于int* p
这里的int *p 不是申明的int了一个 *p 对象,因为 *p是p指针的地址值,这里可以这么理解,int * 是一个申明,申明了一个p指针,而 *p 只是获取 p指针的内容。
- 动态内存分配
cpp中申请内存的关键字是new,不同于c中的malloc。
// 栈内存 int a=1; // 堆内存(存储时间更长) int *a1 = new int(2); cout << *a1 << endl; //2 delete a1; cout << *a1 << endl; //2 a1= nullptr;
new int(2)是申请了一个堆内存空间,大小为int的大小,而内存中所存储的值为2。 申请出来的内存需要手动释放掉,释放空间但是这里我们delete后还能看到可以输出值,其实原理很简单,如下图所示:
- 数组和指针
int array[]={1,2,3,4,5}; int *p=array; cout << *array << endl;// array[0] cout << *p << endl; // array[0] cout << *(p+1) << endl; // array[1] cout << *(p+2) << endl; // array[2]
-
常量指针
- 指向常量的指针
const int *p=&a; // 不能 *p=? int b=2; p=&b;
*p 是只读类型,也就是不能被赋值,编译器就会报错,但是可以改变p的指向。
- 常量指针
int *const q=&a; *q =10;
常量指针与指向常量的指针相反,可以赋值,但不可以改变地址
- 指向常量的常量指针
// 不能修改任何东西的指针 const int *const q=&a;
- 指针参数
#include <vector> void iterator(vector<int> *v){ //v->size(); for (int i = 0; i < (*v).size(); ++i) { cout << (*v)[i]<< endl; } }
- 指针参数关于foreach
void func_iterator(vector<int> *v){ //v->size(); //以下方式不会改变v的内容,因为int v:(*v)相当于又创建了一个v的v的参数。 //for (int v:(*v)) { // 此处应该是 int &v:(*v) // if(v==45){ // v=15; // 此处改变的是int v 和 *v无关 // } //} // 以下方式可以改变*v的内容 for (int i = 0; i < (*v).size(); ++i) { if((*v)[i]==45){ (*v)[i]=15; } } }
-
函数指针
- 返回值指针
int* max(int *a,int *b){ return *a>*b?a:b; }
- 二级指针
void func(int **p){ *p=new int(4); } int *p= nullptr; func(&p); cout << *p << endl; delete p; p= nullptr;
- 函数指针
int add(int a,int b); int blod(int a,int b,int (*add)(int,int)); int main() { //函数名单独使用会转化为指针 //add_param相当于参数,add是函数指针 //函数指针可以作为函数参数传递。 int (*add_param)(int ,int) = add; int result=blod(4,6,add_param); cout << result << endl; return 0; } int add(int a,int b){ return a+b; } // 函数指针的目的是将函数转化为参数 int blod(int a, int b ,int (*add)(int,int)){ return add(a,b); }
- typedef
名称替换(起别名)
//typedef vector<int> vi; typedef int(*add_param)(int,int); int main() { int result=blod(4,6,add); cout << result << endl; return 0; } int add(int a,int b){ return a+b; } int blod(int a, int b ,add_param){ return add(a,b); }
引用
-
引用简介
- 是变量或者对象的别名
- 引用不能改变自己指向
- 申明引用时必须对其初始化
- 引用不会引发新的空间开销
- 引用不能建立数组引用。
-
右值引用
-
左值&右值
不能以等号的左右来判断是否是左值右值。左值: 是否能取地址,或者是否能起名。右值: 具体的数值,或者具体的表达式。
int a = 33; |左值| |右值| int a = b; |左值| |左值| int a = b + 3; |左值| | 右值 | int a = get() // 不能被取地址,虽然它有函数地址和指针 |左值| | 右值 |
左值引用必须都是左值.
int &c =a; get_num(int &v){....}
-
右值引用
为了支持移动概念,添加了右值引用,绑定一个即将销毁的对象,左值具有持久的状态,有独立的内存空间。而右值就是表达式在求职过程中创建的临时对象。
int &&c=4; int &&c=a+4 int a(int &&a,int b){} a(1,2) int b(int &a,int b){} b(c,2)
右值引用必须都是右值.
-
🔗 前言
🔗 C++ 高级列表
🔗 NO.1 C++ 基础
🔗 NO.3 C++ 特殊函数
🔗 NO.4 C++ 重载&继承&lambda
🔗 NO.5 C++ 虚函数&智能指针
🔗 NO.6 C++ I/O
🔗 NO.7 C++ 模版编程&容器
🔗 NO.8 C++ 常用函数&线程
🔗 NO.9 C++ QT 入门
🔗 NO.10 C++ QT 绘制&自定义组合控件
🔗 NO.11 C++ QT 绘制