emm~大家好,本来指针想往后拖亿点,但是,以后要将结构,类什么东西,所以(早点总比晚点强)
目录
1.前言
第五篇讲到的scanf(),参数列表里每一个都带加个&,&是什么???
我们知道,只要是关于电脑的东西,都存到内存里(临时的),包括我们的变量
那么,指针就是用来登记备案号的,暂且可以这样理解。
2.定义
要这样:
<数据类型> * <名称>; //数据类型可以是基础数据类型,结构,类,void
看注释~
比如,我要用p_n指针指向int类型的n:
int n = 12;
int * p_n = &n; //为n的地址
只能把int变量地址赋给int*指针,double类型赋给double*指针,以此类推。
但是有一种指针类型叫void*,可以指向任何类型:
int n;
double d;
char c;
void * p_n = &n; //OK
void * p_d = &d; //OK
void * p_c = &c; //OK
明白了吧~
但是,如果指针暂时不用,我建议你初始化成空指针,有三种方式,都是初始化为空:
void * p1 = 0; //空指针
void * p2 = NULL; //空指针
void * p3 = nullptr; //空指针(C++11)
- 小贴士:如果你用的是比较老或者官网写着不支持C++11的编译器,不要用nullptr初始化
3.使用
使用时要知道:
额,很多人怕指针,其实不需要怕,我告诉你,以下几点你做了,你的指针就没问题:
- 在使用“解除引用运算符”前,给指针赋一个没有歧义(不是空指针,并且指向的内存可以访问)的地址;
- 类型配对使用(尽量不用void);
- 不要内存太大;
- new(或者是malloc(),calloc(),realloc())和delete(或者是free())配对使用。
3.1.动态内存空间
有时候,没有变量,突然要新建一个变量并且有一个指向它的指针,而且还能释放,那就需要用动态内存空间了。
3.1.1.new
这时候可以一步到位,使用new,格式如下:
int * p_a = new int;
new后边的类型必须和前面定义指针的类型一样。
给你们拓展一下:刚才我们使用的new看起来像关键字,但是它其实是个函数,也就是说,上面的最终被转换成:
int * p_a = new(sizeof (int));
顺便说一下sizeof,一枚关键字,用来运算变量或者数据类型占用的内存字节数。运算数据类型时(就像上面)必须加上括号,变量不用(也可以,不是多打几个字吗?)。
那么这一块新的内存没有名字,需要用*p_a使用它。
3.1.2.delete
刚才使用了new给p_a了一块内存,(剧情开始)这时候,我拿着它干完了事情,我不要它了,可以丢一边,也可以丢垃圾桶里回收。
那么delete就是干内存回收的:
delete p_a;
同样,也是一枚函数:
delete(p_a);
3.1.3.malloc()
(使用前加上#include <cstdlib>)
malloc()跟new干一样的事,但是需要类型转换:
int * p_a = (int *) malloc(sizeof (int));
但是也不是一无是处,还可以自定义长度:
int * p_a = (int *) malloc(40);
它还有两个兄弟,calloc()和realloc(),不讲。
3.1.4.free()
(使用前加上#include <cstdlib>)
free()跟delete干一样的事:
free(p_a);
明白了吧,没有什么好讲的。
3.指针数组
可以创建指针组成的数组:
int (* ptr)[15];
指向数组:
int n[15] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int (* p_n) [15] = &n;
也可以有指针的二维数组。
对了,新建指针数组的时候把*和名字放小括号里。(运算符优先级)
3.1. 指针数组指向动态数组
同样,也可以分配动态数组:
int (* ptr)[15] = new int[15]; //new的用法
int (* ptr)[15] = (int *)malloc(sizeof (int) * 15); //malloc()的用法
delete [] ptr; //delete的用法
free(ptr); //free()的用法
4.引用
引用(reference)是C++相对于C的重要扩充。
引用(reference)就是C++对C语言的重要扩充。引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。引用的声明方法:类型标识符 & 引用名=目标变量名;
引用引入了对象的一个同义词。定义引用的表示方法与定义指针相似,只是用&代替了*。
————百度百科
顾名思义:
<类型名>& <引用变量名> = <变量名>;
看一个:
#include <iostream>
using namespace std;
int main() {
int a = 9; //变量
int &b = a; //引用
cout << "a=" << a << ", &b=" << b;
return 0;
}
结果:
a=9, &b=9
引用还可以作为一些需要更改变量本身函数的形参,比如:
#include <iostream>
using namespace std;
void refswap(int &a, int &b) { //使用引用
int temp;
temp = a;
a = b;
b = temp;
}
void ptrswap(int *a, int *b) { //使用指针
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void nrmswap(int a, int b) { //使用形参
int temp;
temp = a;
a = b;
b = temp;
}
int main() {
int a = 9, * p_a = &a;
int b = 8, * p_b = &b;
cout << "a=9, b=8" << endl;
cout << "使用引用交换数值:";
refswap(a, b);
cout << "现在a=" << a << ",b=" << b << endl;
cout << "使用指针交换数值:";
ptrswap(p_a, p_b);
cout << "现在a=" << a << ",b=" << b << endl;
cout << "使用形参交换数值:";
nrmswap(a, b);
cout << "现在a=" << a << ",b=" << b;
return 0;
}
输出:
a=9, b=8
使用引用交换数值:现在a=8,b=9
使用指针交换数值:现在a=9,b=8
使用形参交换数值:现在a=9,b=8
可以看到,引用和指针都成功了,形参没有成功,为什么呢?
看:
明白了吧,
拜~