文章目录
一、指针和引用的区别
1、相同点
都是地址的概念:指针指向一块内存,它的内容是所指内存的地址(逻辑地址);而引用则是某块内存的别名。
2、不同点
-
指针保存的是所指对象的地址(实体),引用仅仅是对象的别名(非实体),指针需要通过解引用间接访问,而引用是直接访问;
-
非空区别:引用不能为空,指针可以为空;
-
可修改区别:引用必须在定义时就初始化并且不能改变所指的对象,而指针可以改变地址,从而改变所指的对象;
-
合法性区别:引用是类型安全的,而指针不是 (引用比指针多了类型检查);
二、引用的概念详解
1、引用作为函数参数
因为引用是对象的别名,实际上和原始对象是同一个对象,不是原始对象的拷贝。所以引用作为函数参数时,传参无须拷贝,提高了效率,另外引用还会改变实参。
void swapint(int &a,int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
swapint(x,y);
2、引用作为函数返回值
如果一个函数返回了引用,那么该函数可以作为左值,进行赋值等操作。
double &max(double &d1,double &d2)
{
return d1>d2?d1:d2;
}
max(x,y) += 1.0;
三、指针的概念详解
1、指针作为函数参数
指针作为函数参数时,形参实际上是实参的一份拷贝,只是分别属于两个不同的指针变量。
#include<stdio.h>
void Try_change(int *q)
{
int b = 7;
q = &b; // p和q原来都是指向a,现在q改变了指向,所以不影响p
}
int main()
{
int *p = NULL;
int a = 5;
p = &a;
printf("main p=%p &p=%p\n", p, &p);
Try_change(p);
printf("%d\n", *p); // 输出5
return 0;
}
#include<stdio.h>
void Try_change(int *q)
{
int b = 7;
*q = b; // p和q都是指向a,而且q改变了原对象的值,所以*p也随之改变
}
int main()
{
int *p = NULL;
int a = 5;
p = &a;
Try_change(p);
printf("%d\n", *p); // 输出7
return 0;
}
void GetMemory(char *p)
{
// p是str的一个副本,本来都指向NULL,但是申请新的内存后p和原来的str就不是
// 同一个东西了,所以会产生内存泄漏,解决方法是使用指向指针的指针。
char *p = new char[100];
}
void main()
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hi"); // str = NULL
}
2、函数指针
函数指针即指向函数的指针。
#include <bits/stdc++.h>
using namespace std;
int add(int a,int b){return a+b;}
int multiply(int a,int b){return a*b;}
int subtract(int a,int b){return a-b;}
int divide(int a,int b){return b!=0 ? a/b : 0;}
bool func(const string &s1, const string &s2)
{
return s1.size() > s2.size() ? true : false;
}
int main()
{
auto pf = &func;//pf是指向函数的指针。
cout << pf("ab","abc") << endl;
typedef int(*p)(int, int);//使用typedef定义指向函数的指针。
vector<p> vec{add,multiply,subtract,divide};
for (auto f : vec)
{
cout << f(2,3) << endl;
}
return 0;
}
3、指针数组和数组指针
指针数组即数组中每一个元素都是指针,而数组指针即指向数组的指针。
int (*p)[4]; // 定义一个数组指针p,指向含4个元素的一维数组。
int *p[3]; // 定义一个指针数组p,p中的每一个元素都是int类型的指针。
4、野指针/悬垂指针
有多个指针都指向了同一个对象,其中一个指针删除了对象后,其余指针就变成了野指针/悬垂指针。
5、this指针
每一个类对象都有一个指向本身的this指针,它有如下特点:
-
this指针只能在成员函数中使用(全局函数、静态函数都不能使用this指针),并且不占用内存空间;
-
this指针在成员函数开始执行时被创造,成员函数结束时被清除;
-
this指针的放置位置和编译器有关,可能是堆、栈、或者寄存器。