指针和引用详解

一、指针和引用的区别

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

C语言中的引用指针有一些区别。下面是它们的主要区别: 1. 语法区别:在C语言中,引用使用&符号来获取变量的地址,而指针使用*符号来声明指针变量和解引用指针。 例如: ```c int num = 10; int *p = &num; // 使用指针获取变量的地址 int &ref = num; // 使用引用获取变量的地址 ``` 2. 操作区别:通过指针可以进行指针运算和修改指针所指向的值,而引用只能在创建时绑定到一个对象,之后无法改变绑定的对象。 例如: ```c int num = 10; int *p = &num; int &ref = num; *p = 20; // 修改指针所指向的值 ref = 30; // 修改引用所绑定的值 p++; // 指针运算 // ref++; // 错误,引用无法修改绑定对象 ``` 3. 空指针和野指针指针可以具有空值(NULL),即未指向任何有效对象。而引用必须始终引用一个有效对象,没有空引用的概念。 例如: ```c int *p = NULL; // 空指针 // int &ref; // 错误,引用必须初始化绑定到一个对象 ``` 4. 传递方式:通过指针传递参数时,可以修改原始数据。而通过引用传递参数时,可以直接修改原始数据,但不能重新绑定到其他对象。 例如: ```c void modifyByPointer(int *p) { *p = 100; } void modifyByReference(int &ref) { ref = 200; } int num = 10; modifyByPointer(&num); // 通过指针修改原始数据 modifyByReference(num); // 通过引用修改原始数据 ``` 总体而言,指针提供了更多的灵活性和功能,可以进行指针运算和动态内存分配等操作。而引用更加简洁、直观,适用于简单的传递参数和别名的场景。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值