什么是指针
1、指针就是地址
利用地址,它的值能直接指向存在电脑存储器另一个地方的值。由于通过地址能找到所需的变量,也可以说,地址指向该变量。因此也将地址形象化为指针。(好比是通过门牌号在一栋大楼里面找到了某一个房间)。
2、指针就是内存编号
内存是电脑上重要的存储器,计算机所有程序的运行都是在内存中进行的,为了有效的使用内存,就把内存划分为了一个个小的内存单元。为了有效访问,给这些内存单元都进行了编号,这些内存编号就是地址。直接上图:
指针变量的类型和大小
指针变量,顾名思义就是储存指针的变量。示例:
int a = 10;
int* pa = &a;
//pa就是指针变量,它储存了整形变量a的地址
//pa也叫做整形指针变量
· 指针变量的类型
char* pc = NULL;
short* ps= NULL;
int* pi = NULL;
long* pl = NULL;
long long* pll = NULL;
float* pf = NULL;
double* pd = NULL;
//初识指针阶段我们所会接触到的类型主要是这几种
· 指针类型的意义
1、指针类型决定了,指针解引用的权限有多大
指针类型发生改变,解引用权限也发生变化
2、指针类型决定了,指针走一步,能走多远(步长)
· 指针变量的大小
提到指针变量的大小,可能理所当然的觉得是于类型相关,实则不然,如下
可以看到所有类型的指针变量的大小都是一样的,可以得出一个结论;
指针变量的大小与类型无关,只与操作系统有关。
64位操作系统下指针大小为8个字节,32位操作系统下指针大小为4个字节
指针的相关概念
· 野指针
概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
形成原因:
1、指针未初始化
int* pa; //没有进行初始化赋值
*pa = 20; //非法访问
2、指针越界访问
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
int* p = arr;
for (i = 0; i <= 11; i++)
{
*(p++) = i;
//当指针指向的位置超出arr数组的范围时,p就是野指针
}
3、指针指向的位置释放
int* test()
{
int a = 10;
return &a;
}
int main()
{
int* p = test();
//函数调用完之后局部变量销毁,指针指向的空间被释放了
*p = 20;
return 0;
}
如何规避
1、指针初始化
2、小心指针越界
3、指针指向空间释放及时置NULL;
4、指针使用之前检查有效性
5、避免返回局部变量的地址
int* test()
{
int a = 10;
return &a;
}
int main()
{
int* p = test();
//函数调用完,局部变量销毁,p没有指向空间
printf("%d\n", *p);
return 0;
}
· 指针运算
1、指针+-整数
会让指向的位置发生变化,(+ - 1)会让指针从指向当前位置变化到指向下一个位置或上一个位置
2、指针-指针
得到的时两个之间的元素个数
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int n = &arr[9] - &arr[0];
//得到的是两个地址之间的元素个数
· 指针的关系运算
int arr[5] = { 0 };
int* p = arr;
for(p = &arr[5]; p > &arr[0]; )
{
*--p = 0;
}
for(p = &arr[4]; p >= &arr[0]; p--)
{
*p = 0;
}
应该避免下面的一种写法,因为标准并不保证可行
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向数组第一个元素前面的那个内存位置的指针比较
· 二级指针
int a = 10;
float f = 10.0;
int* pa = &a;
float* pf = &f; //一级指针变量
int** ppa = &pa;
float** ppf = &pf; //二级指针变量
//同理,有二级指针,那就会有三级指针,四级指针,但是也要看我们自己的需求
初识指针部分就介绍到这里了,如果有不足的地方欢迎大家指正