什么是指针?
- 每个变量都会存放在内存中分配的一个空间,而每种类型的变量所占的空间又是不一样的。
- 每个字节(即房间)都会有一个地址(即房间号),这里的地址就起房间号的作用,即变量存放的位置,而计算机就是通过地址找到某个变量的。变量的地址一般指它占用的字节中第一个字节的地址。
- 在C语言中用“
指针
”来表示内存地址(或者称指针指向了内存地址),而如果这个内存地址恰好是某个变量的地址,那么又称“这个指针指向该变量”。 - 指针就是变量的地址。
- 指针实际上是一个整数,指针是一个
unsigned
类型的整数。
获得变量的地址
- 取地址运算符
&
:在变量前面加上&
。
指针变量
- 指针变量用来存放指针(或者可以理解成地址)
- 在某种数据类型后加星号
*
来表示这是一个指针变量。 - 星号
*
的位置在数据类型之后或是变量名之前都是可以的,编译器不会对此进行区分。
C++
程序员更习惯于把星号放在数据类型之后。 - 指针变量存放的是地址,而
&
则是取地址运算符,因此给指针变量赋值的方式一般是把变量的地址取出来,然后赋给对应类型的指针变量。 - 把星号*视为一把开启房间的钥匙,
*p
就可以访问其房间的值。 - 指针变量支持自增和自减操作
指针与数组
- 数组名称也作为数组的首地址使用
a == &a[0]
a+i == &a[i]
- 两个
int
型的指针相减,等价于在求两个指针之间相差了几个int
。
使用指针变量作为函数参数
- 函数的参数是作为局部变量的,对局部变量的操作不会影响外部的变量,如果想要修改传入的参数,那么只能用指针。
- 指针类型也可以作为函数参数的类型,这时视为把变量的地址传入函数。如果在函数中对这个地址中的元素进行改变,原先的数据就会确定地被改变。也称为“地址传递”。
- 区别值传递和地址传递,举例,使用指针作为参数,交换两个数。
- 函数里临时变量初始化的问题
- 函数参数的传送方式是单向一次性的,main函数传给swap函数的“地址”其实是一个“无符号整型”的数,其本身也跟普通变量一样只是“值传递”,swap函数对地址本身进行修改并不能对main函数里的地址修改,能够使main函数里的数据发生变化的只能是swap函数中对地址指向的数据进行的修改。
引用
引用的含义
- 引用不产生副本,而是给原变量起了个
别名
。 - 对引用变量的操作就是对原变量的操作。
- 不管是否使用引用,函数的参数名和实际传入的参数名可以不同。
#include <iostream>
using namespace std;
void change(int &x){
x = 1;
}
int main(){
int a = 10;
change(a);
cout << a << endl;
return 0;
}
// 输出 1
指针的引用
#include <iostream>
using namespace std;
void swap(int * &p1,int * &p2){
int * temp = p1;
p1 = p2;
p2 = temp;
}
int main(){
int a = 1, b = 2;
int *p1 = &a;
int *p2 = &b;
swap(p1,p2);
cout << *p1 << " " << *p2 << endl;
return 0;
}
//输出 2 1
空指针
- 空指针:指针变量指向内存中编号为0的空间。
- 用途:初始化指针变量。
- 注意:空指针指向的内存是不可以访问的。内存编号0~255为系统占用内存,不允许用户访问。
// 空指针
int *pnew = NULL;
cout << *pnew << endl; // 不能访问,报错了!!!
野指针
- 指针变量指向非法的内存空间。非法:不是我申请的空间。