【C++】一、指针与引用

前言

作者本是java出生,对C++的理解还停留在大学的基础阶段,而今年打算考研,于是对知识进行一个整理归纳。

读本篇文章需要一定的基础,如无基础则先参考看别人写的这两篇做个入门

学习C++最让人头疼的指针、二级指针、引用是什么魔鬼啊?
而要理解这几个概念,一定要了解内存分配规则,因为作者对java的内存分配有一定的了解,所以两者是相通的
如果你是javer请看:jvm内存分析
如果你是新手请看:C++内存管理C/C++内存管理详解

当你理解了底层知识,那么消化上层的知识就像流水般的舒畅~

1.事例代码

对于抽象概念的理解,不要看书,直接上代码,跑起来!

1.1 指针

指针的本质就是指向变量的地址,简单粗暴的修改地址里面的值
*p、&p、p;int& p、int *p是什么鬼?

1.2 二级指针

二级指针存放的是一级指针的地址,为什么要有二级指针?
为什么传一级指针无法修改changeValue?
变量副本是什么?
可以看下面的二级指针changeValue()例子

1.3 引用

解决指针使用麻烦的问题,与指针有啥区别?
引用的本质就是指针!可以理解为引用对指针进行了一层封装。

1.4 值交换

经典问题,参数的引用传递,指针传递。

#include <iostream> //导入输入输出库 
using namespace std;//定义全局命名空间,定义变量std 

void refer();
void swap();
void pointer();
void pointer2();

//方法的声明 
void swap1(int a,int b);
void swap2(int *a,int *b);
void swap3(int& a,int& b);
void changeValue(int *p);
void changeValue2(int **p);
void changeValue3(int& p);

int main()
{
	//1 指针 
//	pointer();

	//2 二级指针 
//	pointer2();

	//3 引用 
//	refer();

	//4 值交换 
//	swap();	


	
	return 0;
}

void refer()
{
    int a = 1;
    int a1 = 2; 
    int& b = a; //引用变量b是a的别名
//	b = a1;//引用声明后无法更改b的地址,这边改的只是b地址所指向的a变量的值 
	
	cout<<"a = "<<a<< ", b ="<<b<<endl;
	
	//地址相同 
    std::cout<<"a:address->"<<&a<<std::endl;
    std::cout<<"A:address->"<<&b<<std::endl;  //注意这里的&是取地址

    a = 10;
    b = 100;//a的值修改了 
    cout<<"a = "<<a<< ", b ="<<b<<endl;

    int& c = b; //引用变量c是引用变量b的别名,别名的别名
    c = 1000;//三个值全部修改 
}


void swap()
{
	int a = 1,b=2;
	int& a1 = a;
	int& b1 = b;
//	swap1(a,b);//传变量的值(在方法内操作的只是temp,改变不了实际ab的值) 
	swap2(&a,&b);//传变量的地址(直接操作内存地址的值,最粗暴的方式 ) 
//	swap3(a1,b1);//传变量的引用 (变量与变量的别名,它们的地址是同一个,直接操作ab的值 ) 
	cout<< a << "," << b; 
}
void swap1(int a,int b)
{
    int tmp = a;
    a = b;
    b = tmp;
}
void swap2(int *a,int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
void swap3(int& a,int& b)
{
    int tmp = a;
    a = b;
    b = tmp;
}


void pointer()
{
	//引用 int& a存放的是别名:&a是地址、a是值
	//指针 int *p存放的是地址:p是地址、*p是值 (注:参数传递中传地址过去 int *p) 

	int  var = 0;   // 实际变量的声明
	int  *ip = NULL;        // 指针变量的声明
	ip = &var;       // 在指针变量中存储 var 的地址
	cout << "var = "<< var <<", ip = " <<ip<<", *ip = "<<*ip<< endl;
	
//	var = 1;
	*ip = 2;
	cout << "var = "<< var <<", ip = " <<ip<<", *ip = "<<*ip<< endl;

	//指针步长 
	ip++;//等于ip当前地址 + sizeof(var),就是把ip的地址指向下一个空间,因为当前空间的int占用了4个,所以要计算上去 
	cout <<"ip++ = "<< ip << " , sizeof(var) = " << sizeof(var) << " , *ip = " << *ip <<endl;

}
 
void pointer2(){
    int  a=10;
    int& b =a;
    int  *q;
    q = &a;
    
    //修改a的值 
    *q = 2;
    printf("%d\n",*q);
//    changeValue(q);//不行
//    changeValue2(&q);//(ok)传二级指针修改值 
//    changeValue3(b);//(ok)直接传引用修改值 
    printf("%d\n",*q);
}
void changeValue(int *p){//传进来的p是a的地址,或者说p只是一个普通变量,这个变量存放了a的地址 
    int  b=100;
    p = &b;//因为p是一个变量,所以,这边的p是个副本_p,对副本进行操作,并不会改变实际a的值 
}
void changeValue2(int **p){//传进来的是p的地址,不是a的地址!! 
    int  b=100;
    *p = &b;//这边虽然也有一个副本_p,但是没有影响,因为*p取到p地址的值,也就是a的地址,然后修改其值 
}
void changeValue3(int& p){
    p = 100;//引用理解为是对指针进行了封装,使用起来简单 
}

2.指针与引用的区别

引用 int& a存放的是别名:&a是地址、a是值
指针int *p存放的是地址:p是地址、*p是值

1、引用只能在定义时初始化一次,之后不能改变指向其他的变量,但指针可以。
2、引用必须指向有效的变量,但指针可以为空。
3、sizeof引用得到的是所指向的变量的大小,但sizeof指针是对象的地址的大小。
4、引用的自增(+ +)自减(- -)是对值的+1或-1,而指针++或–是+或-其所指向的类型大小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值