详解初阶指针

1.指针是什么

首先我们要知道,内存是被划分为一个个内存单元,而每一个内存单元都有一个单独的编号,每一个编号又被我们称之为地址。在C语言中,我们又把地址称为指针,指针是内存中一个最小单元的编号;我们口头中说的指针通常指的是指针变量,是用于存放内存地址的变量。

1.1指针的大小

我们需要知道,在不同的平下,指针的大小是有所不同的。

在32位的机器上,地址是由32个0或1组成的二进制序列,其地址需要用4个字节大小的空间来存储;在64位机器上,地址是由64个0或1组成的二进制序列,其地址需要用8个字节大小的空间来存储。所以,32位台下, 指针大小为4个字节64位平台下,指针大小为8个字节。


2.指针类型

我们都知道,变量有着不同的类型,分为:整形、浮点型、字符型等。同样的,指针也有着不同的类型,不同类型的指针可用于存放不同类型的变量地址(不一定为相同类型指针存储相同类型的变量地址)。 

2.1指针的初始化

指针的初始化是通过:指针类型+ * +指针变量 来定义的,例如:

至于不同类型点的指针类型对于存储变量地址有什么影响,我们马上在后面会讲解到。

2.2指针的运算 

2.21指针+-整数

指针的加减整数相当于是对地址的加减。而指针类型会影响指针加减相同整数大小时地址的增减大小,看以下代码:

 通过上面的代码我们发现,不同类型的pi、pc指针变量,存放的变量n的地址是相同的,这说明指针变量类型并不会影响存储变量的地址,但是我们会发现,pi、pc指针加减整数1时地址改变的大小是不同的,char类型的指针变量pc,加减1,地址大小改变1;int类型的指针变量pi加减1,地址大小改变4。

总结:指针的类型决定了指针向前或者向后走一步的大小。

 2.22指针-指针

指针-指针的运算的前提是需要两个运算的指针是指向同一块空间,运算的结果是得到两指针之间的元素个数差,这个结果可以是负数。例如:

2.3指针的解引用

通过指针的解引用可以访问当前指针储存的变量。

如:

同样的,指针类型的不同也会影响对存储变量的访问,不同类型的指针的解引用操作能够访问的内存大小是不同的。为了更好的了解指针类型的不同对影响存储变量的访问 我们先来看有关整型数在内存中的储存规则。

2.31整形存储中的大小端

整型数在内存当中的存储有两种模式,一种为,大端存储模式,另一种为小端存储模式。大小端的存储在不同编译器环境下有所不同。

  • 大端存储:数据的低位保存在内存的高地址当中,而数据的高位保存在内存的低地址当中。
  • 小端存储:数据的低位保存在内存的低地址当中,而数据的高位保存在内存的高地址当中。

例如,一个2个字节的short型n,其值转换为16进制表示为:0x1122,其中第一个字节存储的数字11为n的高位,第二个字节存储的数字22为n的低位,对于大端存储来说,低位的0x22要放在高地址中存储,高位的0x11要放在低地址中存储,同理小端存储与此相反。

看以下代码:

 我们观察到,不同类型的指针变量pi,pc,在进行解引用遍历地址打印整型数组中的数据时,int型的指针变量能够正确打印出数组数据,而char型的指针变量打印的结果十分奇怪。让我们逐一分析,首先我们大致了解到整型数在内存中的存储规律,就编译器vs来说,其存储模式为小端存储模式,作为不同类型的指针,其解引用操作能够访问的内存大小与其指针类型的字节大小是相同的,如char型指针解引用只能访问1个字节的内存空间,而int型的指针解引用则能够访问4个字节大小的内存空间,这里的char型指针变量加1,地址增加1,int型的0转换为16进制的形式为0x 00 00 00 00,char型指针依次访问一个字节大小的地址,则分别打印出4个0,int型的1转换为16进制为0x 00 00 01,由于是小端存储,低位的01放于低地址存储,先被访问,于是就紧接着打印了数字1以及三个零,同理2和0 的打印也是如此。

总结:指针的类型决定了对指针解引用时的权限(能访问操作几个字节大小的空间),这个大小与指针类型所占字节大小相同。


3.野指针

概念:野指针是指指针所指向的位置是未知的(随机的,不正确的,没有明确限制的)

3.1野指针的成因

1.指针未初始化,如:

 在定义指针时,需要给指针变量赋值,否则该指针指向的空间就是随机的间。为避免指针未初始化造成的野指针,如果我们不清出该指针要指向哪一地址的话,我们可以给指针置空,即赋值NULL。

2.指针越界访问,如:

 该代码中,指针p指向的范围超出了数组arr的范围,导致了野指针的产生。为避免越界产生的野指针,我们在处理数组相关的问题时,要更加注意数组的有效范围。

3.指针所指向的空间被释放

这种野指针的成因相对于前两种来说比较少见,但是却是最不容易察觉的野指针,虽然前面两种野指针的成因更加常见,但是可以通过编译器的报错来得知,而这种野指针的产生编译器甚至不会报错,需要我们自己去发现,也许你下一个的野指针就是由这种粗心导致的,如:

 我们可以看到这种野指针的产生的确可以正常编译产生结果,但又确实是野指针,看似不起眼的小bug有时能成为影响一个巨大工程的成败。看上面代码我们知道,指针变量接收了test()函数调用的返回值,而test()函数的的返回值所指向的空间是函数临时创建的一个变量地址,一旦离开函数临时变量就将会被销毁,此时所存储的变量是未知的,如果再通过指针去访问这一块地址的变量,就会造成野指针的产生。


4.二级指针

与指针相同,二级指针也是用来存储地址的,不同的是,二级指针是用于存储指针变量地址的指针, 通过对二级指针变量的解引用可以访问一级指针变量。例如:


结语:

本期操作符的相关知识到这就介绍完了,如果感觉对你有帮助的话还请点个赞支持一下!有不对或者需要改正的地方还请指正,感谢各位的观看。


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值