一、指针是什么
在计算机中,指针式编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,降低至形象化的称为“指针”。意思就是他能找到以他为地址的内存单元。
内存:内存是电脑上特别重要的存储器,计算机上的所有程序都是在内存中运行的。所以为了有效使用内存,就把内存划分成一个个小小的内存单元,每个内存单元的大小是1字节。
为了能够有效访问的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为内存单元的地址。
电脑有32位地址线和64根地址线之分,一旦通电就有了正电(1)与负电之分(0)(电信号转化为数字信号)而这些数字信号就组成了一系列的0、1序列一共有2^32次方种可能。(32根地址线为例),这些序列就组成了内存编码,每个内存编码占一个字节。
总结:指针是个变量,存放内存单元的地址。(指针是用来存放地址的变量)
#include<stdio.h>
int main()
{
int a=10;
int* p=&a;//指针变量
return 0;
}
这里我们能知道:
1、在32位的机器上,地址是32个0或1组成的二进制序列,那地址就要用4个字节的空间来存储,所以一个指针变量的大小应该是4个字节;
2、同样的在64位的机器上,地址是64个0或1组成的二进制序列,那地址就要用8个字节的空间来存储,所以一个指针变量的大小应该是8个字节。
#include<stdio.h>
int main()
{
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(char*));
printf("%d\n", sizeof(float*));
printf("%d\n", sizeof(long*));
printf("%d\n", sizeof(short*));
return 0;
}
总结:
1、指针是用来存放地址的,地址是唯一标示一块地址空间的;
2、指针的大小在32位平台是4字节,在64位平台是8字节。
二、指针和指针类型
指针也有其自己的指针类型
我们可以看到,既然指针类型的大小都为8,那为什么要区分呢?用一种通用的指针类型不行吗?
当然是不可以的,因为指针类型具有一定的实际意义,下面我们就来看一下指针类型的实际意义:
不管是char*类型还是int*的指针都能够很好的存放好a的地址,那区别在哪里呢?
在这里我们打开调试窗口,输入&a就可以找到a的地址,是倒着读的11 22 33 44,然后我们借用操作后发现a的地址变为:00 00 00 00
但是如果我们把指针类型改为char*的话 ,在进行解引用操作时,内存里的4个字节我们仅仅只操作了1个字节,这便是指针类型有区别的原因
指针类型的意义:指针类型决定了指针进行解引用操作时能够访问空间的大小的权限。比如:int*能够操作4个字节,short*能够操作2个字节等等。
除此之外指针类型还有一个意义:
指针+-整数
#include<stdio.h>
int main()
{
int a = 0x11223344;
int* p = &a;
char* q = &a;
printf("%p\n", p);
printf("%p\n", p+1);
printf("%p\n", q);
printf("%p\n", q+1);
return 0;
}
在这里我们就可以很明显看到区别:前两个相差了4个字节而后面两个相差了1个字节
指针类型决定了指针走一步有多长(指针步长)比如:int* p;p+1-->4;char* p;p+1-->1
应用:我们可以把一个数组中的元素全部改成同一个值
#include<stdio.h>
int main()
{
int arr[10]={0};
int* p=arr;//数组名是首元素地址
int i=0;
for(i=0;i<10;i++)
{
*(p+i)=1;
}
return 0;
}
三、野指针
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
野指针的成因:
1、指针未初始化
#include<stdio.h>
int main()
{
int* p;//局部变量指针未初始化,默认为随机值
*p=20;
return 0;
}
2、指针越界访问
#include<stdio.h>
int main()
{
int arr[10]={0};
int*p=arr;
int i=0;
for(i=0;i<=11;i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*(p++)=i;
}
return 0;
}
3、指针指向的空间释放举个栗子:
#include<stdio.h>
int* test()
{
int a = 10;
return &a;
}
//函数一结束开辟出来的a的空间就已经还给系统了,不属于我们当前编译器
int main()
{
int* p=test();
*p = 20;
return 0;
}
//也就是说虽然地址已经保存了,但指针指向的位置不可知,电脑可能已经把他分配给别的数组了,不能随便修改了
如何避免野指针
1、指针初始化
2、小心指针越界
3、指针指向空间释放及时置NULL
4、指针使用之前检查有效性
结语 :
本次分享就先到这里,相信大家通过这篇文章一定会有所收获。感谢大家的关注和观看!