Poedu_C语言_lesson22_20160927_函数2

指针基本上都是在跨函数的情境下使用,指针有着强大的功能,但是我们在使用指针的时候要注意指针类型的设定。我们来看看下面代码:


在上述代码中,因为是个小小的实验,所以我在函数的内部进行了指针的操作,但是大家一定要清楚,指针更多的是用于跨函数的情形下,在同一个函数内是极少这样操作的。我对第一部分的代码进行了注释,在此就不赘述了,我们直接来看运行效果吧:

首先是指针类型与数据类型相同时的情况:


下面内存中,即是num的地址,与输出的pnum的值是相同的。此时并没有输出pnum++之后的值,或许你会认为“++“”的操作就是自身+1,如果你没有做过类似的尝试,可以试着猜想一下,当前pnum的值应该是多少。让我们来看一下答案:


当前pnum所保存的地址是:002FF8F4,与原地址002FF8F0比较,是加了1么?不是的,是加的4,。为什么呢?自加不是都应该加1的么?指针所进行的运算不是纯粹的加减,而是通过偏移,“++“”的时候,加的是数据类型的长度(当前是int型,所以加的是4)。通过指针的偏移,可以更快的访问同一类数据。比如我们的int型数组中的a[0]与a[1],代表着两个int型的数据,当我们对数组进行遍历的时候,依靠的就是指针的偏移。

由此,下面代码中出现的pchar++和pdouble++的值应该是可以算了吧?可以自己计算一下,然后待会儿看结果。

接下来,用一个char类型的指针指向了int型的num,这样不是不对的么?应该类型相同啊,不会报错么?是的,编译器不会报错,但是会有警告,然而警告并不会让我们不能运行程序...有兴趣的朋友可以自己试试。

我们来看看这样错误的指向会发生什么问题:


结果中的“d”是因为我们以“%c”的形式对*pchar进行了输出,自加后pchar的值与原来的值相比,只增加了1(char型的长度)。最为关键的是,输出的值还是100。没问题啊!错误指向也没问题啊。其实,是有问题的,但是在这里没有暴露出来。什么问题呢?我们知道,char类型是只占一个字节,那么当我们对char型的指针就行解引用(*pchar)的操作后,首先,会找到pchar所保存的地址(即num的地址),而后读取一个字节。大家可以看上面内存,在0x002FF8F0(num的地址),保存了“64 00 00 00 ”这些数值,64是什么?就是我们十进制的100,我们现在所看到的是以十六进制的格式呈现的。也就是说,我们当前的100只占用了4个字节中的一个。而char刚好指向了这个,所以,呈现出来的结果就没问题了,什么时候会有问题?当十进制数值大于100之后,比如1000,它就需要占用2个字节,到时候再用char型指向,读取的还是第一个字节的数值,这里我就不截图了,可以自己动手试试...

或许你还会有疑问,为什么以%c格式输出是“d”?对于这点,请你使用ASCII码表进行查询...

下面我们接着看一下double类型的指针指向int型数据会发生什么:


程序运行到以%c格式输出,完全没问题,如果你有这样的疑问:如果我现在的int是1000呢?输出的%d会不会出问题?有这疑问的朋友,请考虑下double型的数据长度,还可以动手试试,如还有疑问,可提出来,我们一起探讨。

我们接着运行程序,以%lf的格式输出,很标准啊,double型的数据本来就应该用%lf来输出啊。那你可以猜猜现在输出的数值应该是多少,有猜想后,再来看下面运行的结果:


是不是很吃惊...为啥呢?

首先,我们要清楚一件事情,那就是浮点数和整数的存储方式是不一样的, 如果你做过用麦粒填充棋格的问题,那么你会发现,你用了所有的整型数据类型来存储需要的麦粒数量,最后肯定都是不够的。为什么?因为就算unsigned int 型,它也就是64位而已,最多只能表示2^64,可是我们的麦粒在第64格的时候,它这一格的值就是2^64了,再加上前面的,它就装不下了。怎么办?用double存储。虽然double所占的位数也就是32位,加上unsigned也就是64位了,应该也是不行啊。但是,如果你实际操作了,你会发现是可行的,这就是因为浮点型数据与整型数据的存储方式不一样。

搞清楚了这点,那么,让double来解析int型,其结果是怎样的?很难知道,不能说一定不能知道,因为通过计算还是可以计算出来的。

再后面,就是pdouble++了,应该加多少呢?你是否有答案了?我们来看一下结果:


与原地址相比,加了8,也就是double类型的字节长度


指针的自加操作,可以让我们很方便的做到一些事情,比如同类数据的管理。但是也是危险的,因为可能由于你的疏忽,会使得指针指向一块未知的空间。指向了未知空间,如果你仅仅是读取数据,那还好点,不会造成什么危害。如果你要改写信息了,就可能造成程序的崩溃,因为你不能确定指针现在指向哪,改变的数据是用来干嘛的。

比如double类型指向int型,double型指针可以从指向的位置开始填充8个字节,而int所占用的是4字节,那么如果用pdouble改写int,内容会向下填充,一些有效数据可能会被覆盖。
=>为了避免这个问题,VS这个编译器检查到你在进行这样的操作时,会向多出来的空间填充垃圾值,以保证安全


感谢阅读!

如有错误,欢迎指正!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值