文章目录

  • 一、指针和引用的区别
  • 1、相同点
  • 2、不同点
  • 二、引用的概念详解
  • 1、引用作为函数参数
  • 2、引用作为函数返回值
  • 三、指针的概念详解
  • 1、指针作为函数参数
  • 2、函数指针
  • 3、指针数组和数组指针
  • 4、野指针/悬垂指针
  • 5、this指针


一、指针和引用的区别

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指针的放置位置和编译器有关,可能是堆、栈、或者寄存器