空指针
空指针是一类可以指向任何数据类型的指针类型,定义方式为 void* 变量名
int a = 10;
char b = 'A';
float c = 12.432;
void *pA = &a;
void *pB = &b;
void *pC = &c;
怎样把空指针类型强制转换成其他非指针类型? 一开始我想到了这样去做:
int a1 = static_cast<int>(*pA);
这样编译器会报错,正确的方法应该如下:
int a1 = *static_cast<int*>(pA)
指针常量与常量指针
指针常量
int* const PA = &A; //指针值无法被改变,但指向的资源可以被改变
常量指针
const int* PB = &B; //指向的资源无法被改变,但可以改变指针
如果我们既不想指针被重新赋值也不想资源被重新赋值,这时只要加上两个const就可以了
const int* const *PC = &C
野指针
野指针时指向一个非法的已经被销毁的内存的指针,会对系统造成不可预估的损害,所以我们应该在指针使用周期结束后及时释放指针所占用的内存。
delete a2;
a2 = nullptr;//释放地址,删除指针,将无效指针制空
或者我们使用STL中封装好的智能指针来进自动析构指针所占用的内存
指向一维数组的指针
我们定义了一个数组,这个数组名本身就是一个指向数组第一个元素的指针
int a[5] = { 1,2,3,4,5 };
这里a就是一个指针,指向数组内部元素 1,我们可以通过移动其地址来遍历其中的元素
auto *p = a;
cout << *p << endl; //首地址
cout << *(++p) << endl; //指向下一个地址 每次++都会改变指针变量的值
指针数组:一个存放指针(内存地址)的数组
int* PAArray[3] = { a,&a[1],p };
for (auto p : PAArray) {
cout << p << endl;
}
承接上面的数组a,我们在PAArray中放满了地址
指向二维数组的指针:
指向二维数组的指针有一些复杂,我们定义了一个二维数组如下:
int b[2][3] = { {1,2,3},{4,5,6} };
如果我们像一维数组一样去调用数组名作为指针,如b[0],b[0]+1,假如我们尝试这样去移动指针,得到的只是普通地址的变化
而非元素所在地址.因为b[0],b[1]在这里普通指针
这里我们应该定义行指针来执行相关操作,格式 类型 (* 指针名)[N] = 二维数组
int(*q)[3] = b;
如我们我们像移动一维数组一样移动该指针,指针便会指向每一行元素的第一个元素,遍历方法如下:
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
cout << *(q[i] + j) << " ";
}
}
练习:分别使用二维数组指针和指针数组来存储字符串:
const char **multiarrayPoinyer = new const char *[3]{ "a","abcd","abcdefg" };
const char(*pArra)[10] = new char[3][10]{ "a","abcd","abcdefg" };
函数指针:
函数指针,顾名思义,就是指向函数的一个指针
格式: typedef 返回值类型 (*指针名)(参数列表....)
举个例子如下:
int sum(int a, int b)
{
return a + b;
}
typedef int(*PSUM)(int, int); //通过函数指针类型定义变量
PSUM pSum3 = sum;
但如果函数的返回形式也是函数指针,那该怎么办呢,我们需要定义指向函数指针的指针、
PSUM2 psumttt(int) { //函数的返回值是上面那个函数指针
return NULL;
}
int(* (*p)(int))(int);
p = psumttt;