指针是什么? 有什么用? 有什么优点?
在这里你都能找到答案。本文纯手打,非常适合新手小白
目录
指针
概念
一个变量有两个自身属性——值和地址。正如一个保险箱,既有它里面存放的个人物品,比如一百块钱,又有它自身所在的位置,比如0x0022号。
而指针也是一种变量,不过该变量是一个包含另一个变量地址的变量,仅用于指向别的东西。指针代表的这个保险箱,它里面不再存放个人物品,而是一张纸条,上面写着另一个保险箱的地址0x3212号,你可以根据这个地址找到甚至修改你的个人物品。
那么指针到底有什么用呢?
C++中函数有时要向另一个函数发送大量数据。有两个办法:
(1)拷贝所有的数据并传过去
(2)只传递该数据的地址
一个是复制粘贴,创造出一个副本,另一个是创建快捷方式。有没注意到,第(2)种方法在传递数据位置时很高效,并且它可以修改原始值。就像保险柜一样,在一个保险柜中存放另一个保险柜的地址,相当于你告诉了别人另一个保险柜的位置,他就可以根据纸条跑到另一个保险柜去修改原始数据。相反,第(1)种方法的所有操作都只影响临时拷贝。
得出结论:指针作用
(1)传递数据位置时很高效
(2)可以修改原始值
声明和使用指针
//声明
int* p; 表示指针p指向int类型的数据对象,p存放的是int型的变量地址
//使用
int n=0;
p= &n ; “&”是取址操作符,把n的地址传给p,p此时指向n,所以可以用p来操作n,
但如何操作呢?此时就需要间接寻址操作符“*”
*p=5 “*” 可以使一切操作都只是对p指向的对象,而不修改P指针;此时p指向n,可以用p来操作n。
语句等同于n=5
总之,当p指向n时,*p和n具有同等效果
引用
引用的概念、理解
引用可以理解成给变量起别名。 a 和 b 指向相同的值和内存单元
int& b = a;
在这里 & 不是取地址操作符,而是类型标识符的一部分。表示一个指向 int 类型的引用变量。
但引用本质上,就是一个指针常量,也就是该指针自身的值是一个常量,始终指向同一个地址。
int &ref=a; 实质是 int * const ref=&a
a 和 ref 作用于同一个内存地址
引用注意事项
(1)引用必须初始化,并且不能更改==只能是一个变量的别名
因为b的地址是根据即将要引用的变量a的地址来分配。
用途、适用情况
(1)引用做函数参数
如果把引用作为函数的参数,起到的作用就是形参为实参的别名,所改变的就是实参,相当于取地址的操作。
优点:与指针相比,可以简化指针而修改实参
(2)引用做函数返回值
注意:1、不要返回局部变量的引用
int& test(){
int a=10; a为局部变量
return a;
}
int main(){
int &ref=test(); 出错.因为此时已经将test()作为a的别名,而a为局部变量,储存在栈区,在调用函数
之后会释放
}
2、函数调用可作为左值
int & test(){
static int a=10; return a; //静态变量,存储在全局区
}
int& ref=test();//正确,
其他
区别比较
......(后续补充)
指针参数传递和引用参数传递
引用传递和指数传递的效果是一样的,但语法更简单。
例:交换两值的指针传递和引用传递
#include<iostream>
using namespace std;
void swap(int a, int b)
{
int c;
c = a;a = b;b = c;
}
void swap1(int *a, int *b)//使用指针,交换地址实现数字变换
{
int c;
c = *a;
*a =*b;
*b = c;
}
void swap2(int& a, int& b)//使用引用,a,b是实参的别名,相当于对实参的调用
{
int c;
c = a;
a = b;
b = c;
}
int main()
{
int x = 1;
int y = 2;
swap(x, y);
cout << x << "," << y << endl;
swap1(&x, &y);
cout << x << "," << y << endl;
swap2(x, y);
cout << x << "," << y << endl;
return 0;
}
指针常量、引用常量、常量指针、常量引用
指针常量——指针类型的常量(int *const p)
本质上一个常量,指针用来说明常量的类型,表示该常量是一个指针类型的常量。在指针常量中,指针自身的值是一个常量,不可改变,始终指向同一个地址。在定义的同时必须初始化。
举个例子,该保险箱里的纸条用胶水粘死了,不能移动,始终指向另个保险箱;但是可以根据纸条找到另一个保险箱,然后随意修改其中内容。
用法如下:
int a = 10, b = 20;
int * const p = &a;
*p = 30; // p指向的地址是一定的,但其内容可以修改
常量指针——指向“常量”的指针(const int *p, int const *p)
常量指针本质上是一个指针,常量表示指针指向的内容,说明该指针指向一个“常量”。在常量指针中,指针指向的内容是不可改变的,指针看起来好像指向了一个常量。
举个例子,该保险箱和纸条没有粘在一起,可以随意更换纸条,不必始终指向原来的保险箱;但纸条上的字用黑笔写的,无法擦掉修改,也就是无论指向哪个保险箱,保险箱里的内容你都不知道。保险箱(==指针)还是那个正常的保险箱,只是它纸条指向的被封装了(==常量)。
用法如下:
int a = 10, b = 20;
const int *p = &a;
p = &b; // 指针可以指向其他地址,但是内容不可以改变
常量引用
void foo(const int& n);