什么是指针呢?
目录
一、指针是什么?
指针就是地址,口语中说的指针通常指的是指针变量。
指针变量可以通过&(取地址操作符)取出变量的内存其实地址,把地址存放在一个变量中,这个变量就是指针变量。
#include<cstdio>
int main()
{
int a = 10; //内存中开辟一块空间
int* p = &a; //取出变量a的地址
//a变量占4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量中,p就是一个指针变量
return 0;
}
指针变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)
#include<cstdio>
int main()
{
int* pa;
char* pc;
float* pf;
printf("%d\n", sizeof(pa));
printf("%d\n", sizeof(pc));
printf("%d\n", sizeof(pf));
return 0;
}
运行结果:
4
4
4
指针的大小在32位平台是4个字节,在64位平台是8个字节。
二、指针和指针类型
变量有不同的类型,那指针呢?
char* pc = NULL; //char*类型的指针是为了存放char类型变量的地址
int* pi = NULL; //int*类型的指针是为了存放int类型变量的地址
short* ps = NULL; //short*类型的指针是为了存放short类型变量的地址
long* pl = NULL; //long*类型的指针是为了存放long类型变量的地址
float* pf = NULL; //float*类型的指针是为了存放float类型变量的地址
double* pd = NULL; //double*类型的指针是为了存放double类型变量的地址
指针的定义方式是:type+*。
那指针类型的意义 是什么?
2.1.指针+-整数
#include<cstdio>
int main()
{
int n = 10;
char* pc = (char*)&n;
int* pi = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc + 1);
printf("%p\n", pi);
printf("%p\n", pi + 1);
return 0;
}
运行结果:
006FFB08
006FFB08
006FFB09
006FFB08
006FFB0C
pc+1相当于跳过一个字符,pi+1相当于跳过一个整型
指针的类型决定了向前或者向后一走一步有多大(距离)。
2.2.指针的解引用
#include<cstdio>
int main()
{
int n = 0x11223344; //十六进制
char* pc = (char*)&n;
*pc = 0;
return 0;
}
通过内存查看n的值
*pc=0;赋值前
*pc=0;赋值后
而
#include<cstdio>
int main()
{
int n = 0x11223344; //十六进制
int* pi = &n;
*pi = 0;
return 0;
}
通过内存查看n的值
pi=0;赋值前
pi=0;赋值后
发现char*的指针解引用就只能访问1个字节,而int*的指针解引用就能访问4个字节。
指针的类型决定了对指针引用的时候有多大权限(能操作几个字节)。
三、野指针
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的) 。
3.1.野指针成因
1.指针未初始化
局部变量指针未初始化,默认为随机值。
2.指针访问越界
3.指针指向的空间释放
3.2.如何规避野指针
1.指针初始化
2.小心指针越界
3.指针指向空间释放及时置NULL
4.避免返回局部变量的地址
5.指针使用之前检查有效性
#include<cstdio>
int main()
{
int* p = NULL;
int a = 10;
p = &a;
if (p != NULL) //检查指针有效性
*p = 20;
return 0;
}
四、二级指针
指针变量也是变量,是变量就有地址,那指针变量存放在哪儿呢?
int a = 10;
int* pa = &a; //a的地址存放在pa中,
int** ppa = &pa; //pa的地址存放在ppa中
*ppa通过对ppa中的地址进行解引用,这样找的是pa,*ppa其实访问的就是pa