指针—老顽童

    《忠犬八公》里面说八公的智商相当于六七岁的顽童,周伯通是一个顽童。只是他的年龄不好估计,不过超过10岁的还能是顽童么?好吧,小于10岁,大于7岁,成熟点。大凡这个年龄段的顽童总是让人又爱又恨。顽皮的可爱,可爱的顽皮。能干的事儿不好好干,不能干的事儿却时时逞能。而且在往往之间会做出令所有的人都惊异异常的事情,不喜欢按照常规出牌,不走寻常路,不想平常人所想,这就是顽童。这就是c语言中的指针!左右互博、空明拳,一直到最后的返老还童这都是指针的绝活。

    指针为什么能有这么大的能耐呢?这个我们得从c标准草案中对指针的描述说起,在c标准草案中对指针的描述是:“A pointer type may be derived from a function type, an object type, or an incomplete type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type.”。用我那蹩脚的英文翻译就是:“指针类型可以脱胎自函数实体、对象实体、甚至是一个没有定义的实体。但是通过它的值则肯定可以找到他所引用的对象实体。”

        Ok。标准里面这段话的描述的其实就是对“空明拳”的英文表述。不信我们可以看看老顽童对空明拳总决的说法“以空而明,以虚击实,以不足胜有余”。啥意思?意思就是因为什么都不是,所以什么都是;因为没啥用处,所以用处多多。对比指针,我们看到的是指针的值可以标识任何东西,无论这个东西是函数,实体还是其他什么没有定义的东西。但是总是能够通过它来找到他要表示的对象。

    那么指针要怎么做才能通过它的值来找到他所引用的实体呢?最简单的方法就是给每个实体都编个号,然后通过指针的值来记录这个号,然后就可以通过这个号来找到实体了。嗯,不错这个想法不错。就这么干。那么一个系统中有多少需要标识的实体呢?28次方个?不够吧,但也能用;216次方呢?64k个,还是有点少,不过既然256个我们都能忍受,64k用用也无妨;220次方呢?1M个,曾经看来是不多也不少刚好,可是咋看着那么怪呢?怪不怪不要紧能用就行,于是我们也用了好多年,直到现在有些地方还在用;232次方呢?4G!嗯。这次应该是够用了,于是在好多年中我们都在用4G个标识符来标识我们在计算机世界中创造的各种各样的奇奇怪怪的东西。

     可是bt的人们总是在创造需求,比如说我要看DVD,还是高清D9的那种,这时候就会发现d9的影片至少有了4G以上的东西,这种情况下232次方虽然足够大但也是不够啊,看来还得扩充;264次方?步骤化的思维就给出了这么一个步骤化的解决方案了。听起来很合理,可是用4g来标识计算机世界里面的实体已经持续了太久太久的时间了,在这漫长的岁月中我们使用4g来作为标识总数的计算机家族已经是家大业大了,已经不是会为了一个d9而作出太多的改变的庞大家族了。--编外语:可恶的旧势力啊。总是那么反动。

    于是在唾骂之余就有了使用两个32位整数来凑活的标识大于4g的解决方案,反正cpu足够快不在乎多读一次。你咬我啊。这种解决方案虽然恶心,但是可行,所以在各家的os上面就纷纷出现了类似lseek之类的变通方案,虽然不爽,但是省的到处骂仗,就这么憋着,也能用。谁会为一个d9去做太多的改动啊。可是有了开头的就有后续的,架不住超过4g表示的物件越来越多啊。终于在沉默中有人爆发了,终于有一个憋不住的叫AMD的家伙出来骂街了,偏要用64位,而且还就造出了直接支持264次方个标识的cpu。于是我们就看到了一些支持64位的软件就有了AMD64的标签。指针能标识多少个实体就  在这骂街声中多少达成了共识,定为264次方个。空明拳的基本框架就这么练成了。

     标识数量的问题是解决了,可是标识号的规则呢?因为我们总是要根据标识号来找到标识内容的啊。关于这个话题,懒人总是有最简单的法子,法子就是我们把内存位置按照Byte(一般认为是8bit,能表示256个数字)大小一字排开从0开始编号,这样我们的实体只要在内存中,我们都能知道这个实体的所在的起始位置的编号,通过这个编号就能找到这个实体。方便,真是方便啊。不过我们要人性化,计算机中找实体要通过编号,现实中找人要地址。编号和地址无非是表述不同,本质都一样的。好,那我们就把这个编号叫地址吧,计算机中的内存地址!

     俗话说“龙行一步,鳖爬半年”,什么都能表示,什么都能找得到的指针,在静态情况下是多大?步进一步又是多大呢?不着急,我们到了讨论老顽童的第二项绝技左右互博术的时候了。左右互博术不能增长功力,不能增长招数,但是能增加技能点,而且是成倍的增加技能点。

    那么闲话少说,我们一起来看看这神奇的指针到底在静态的状态下是多大?我们前面讨论过,指针的值是用来标识对象的。所以当我们只需标识256个对象是,指针只需要8位就足够让这个256个对象的编号不重复了;但当需要标识65535个对象时,我们就需要16位才能保证所有的对象不重复;更近一步当我们需要40多亿个对象的时候我们至少需要32位的长度来保证;以此类推当大于40亿的时候我们就需要大于32位的长度来保证,根据砖家们的考证我们其实用128位就可以标识尽这世间万物。可是搞计算机的,尤其是搞c的都精打细算日子过惯了。舍不得啊,当年16cup寄存器长度20位寻址长度这种事情都能干出来,现在还幻想着直接上128位的指针,貌似路漫漫啊。

闲话少叙,一个指针的大小到底是多少呢?这个问题貌似简单,可是从来都不曾简单过。就从最常用的x86系列cpu来说都是因时而异。更遑论其他系列的cpu。在x86的世界里我用过near来表示只有16位的指针,用far来表示过20位的指针,用huge来表示过32位的指针,至于现在嘛,咳咳,看你的编译器定义。偷巧的记忆方式是在32位的编译器下一般是32位,在64位的编译器下一般是64位。可是这些并没有涉及到什么内存扩展技术,不然如果涉及到那些,你还得老老实实的去参考编译器的实现。不然是要吃大亏的。每每想到此就感觉还是解释语言省事省脑细胞啊。

指针的大小解释过了,那么指针的步进又当如何理解呢?在Pascal里面好理解,因为Pascal里面有一个专门的inc函数帮助我们已经处理掉了,可是c里面从来都是什么事儿都得自己干,那么如何干呢?指针引用的对象乱七八糟,其小到引用一个字节,其大到引用整个内存空间甚至硬盘空间,他的下一个引用对象的位置当如何确定呢?

我们知道指针都是要指向一个具体对象的,而每一个对象的大小我们都是知道的,ok,这样处理就简单了。想想如果直接给指针的地址加上这个对象的大小不就成功的越过了这个对象么?既然越过了所引用的对象不就步进成功了么?不错确实成功了,可是比较繁琐,而且机械。有没有简单一点的办法呢?有,这么机械且繁琐的事儿就让编译器去做吧,反正只要告知了编译器指针所引用的类型,编译器就能在编译期间计算错类型的的大小,只要再定义一个步进符号,编译器就能够把这个事儿给办了。++前进,--后退如何?简单明了。好,那就这么定了,c的指针的步进就这么定下来了成了标准。这看起来似乎很完美。可是有人说了,如果知道所引用的对象的类型固然好办,那要是不知道所引用的对象的类型呢?不知道类型的步进对编译器来说确实难办,于是这个问题就留给了写这段代码的人,因为写的人总是知道指针所引用的对象的啊,如果写这段程序的人都不知道,那就只好问上帝了。嘿嘿,挺好,问上帝。不信你问问编译器,他肯定拒绝给你假设(Pascal对无类型指针也是没法处理的,不厚道的偷着乐一下)。

指针的基本概念和基本用法都说完了,那么我来看看指针这个玩意儿到底能干什么?指针其实什么都不能干除了能够引用对象J.有所谓重剑无锋,大巧不工,各位看官请看我在其他章节给你尝试着舞舞这柄重剑。

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。、资源 5来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。、资 5源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值