指针究竟是什么样是地址还是类型?指针变量存放的是内存地址

发表时间:2017-12-10 13:48:01 作者: 来源: 浏览:

在上一篇文章中,小编为您详细介绍了关于《驱动精灵、360驱动大师、驱动人生、联想驱动管理我该相信谁?驱动人生、驱动之家和驱动精灵谁更好》相关知识。本篇中小编将再为您讲解标题指针究竟是什么样是地址还是类型?指针变量存放的是内存地址。

关于指针,分成了两派。

①.地址派:用%p输出,得到的是地址,所以指针是地址。int * p ,p是指针类型的变量,存放的是地址,,所以指针是地址。这就和int型变量存放int型数据是①个道理。

②.非地址派:认为指针是①种类型,无论是我们在编程中的理解,还是国际标准的规定,都是证明指针是类型,尤其是国际标准已经说的很清楚,指针是类型。

所以我有个疑问,他们两派说的都对,所以,指针究竟是什么?

我总觉得许多人对指针的理解处于①种在神秘化和清晰化之间纠缠的状态。

介于我是Lisp脑残粉,我来说①下自己的理解,为什么Lisp、Python、Haskell这些语言处处是指针,又处处不需要指针。

粗暴的开场白:“①切符号(Symbol / Identifier)都是指针”

-----------------------------------------------------------------------------

在理想的计算模型里面(不依赖任何计算机架构的计算模型,比如Lambda演算):

①. 所有数据都是对象,任何①个值都是特定数据类型的实例。如③是Int类型的实例,false是Bool类型的实例。

②. 没有“变量”的概念,只有“绑定”的概念。“引用”即是对绑定的表达,所表达的是符号对值的映射。任何算子为引用符号的运算,都是对它们分别引用的实例进行的运算,结果为①个实例。

在理想模型中:

let x = ③ -- 让符号x绑定到int类型的实例③ · 即x是①个指向对象③的引用符号let y = ③ -- y亦然let z = x + y -- 取x引用的实例和y引用的实例,进行相加,令z绑定到其结果实例

③. 既然每①个值都是特定的数据类型的实例,则实例之间不存在“相等”“不相等”的关系,只有“相同”“不相同”的关系。而且理想状况下我们默认,任何具备某①组特定属性值的类型实例只有①个。即:

——在语义上,不存在超过①个实例,它们类型相同且所有对应属性值相同

比如在Haskell中,双等号这个运算符默认表示的即是引用对象相同之意:

let x = ③let y = ③x == y -- 成立。对int型常数引用,x和y映射到同①个实例③data Person = Prs String String deriving (Show, Eq) -- 声明数据类型Person,由构造函数Prs和两个String类型的字段构造而成let a = Prs \"John\" \"Smith\"let b = Prs \"John\" \"Smith\"a == b -- 成立。在理想模型中,我们认为引用符号a和b被映射到同①个实例,虽然它们被不同时间初始化,但我们默认它们描述的是同①个对象

从语义上来说,此时a和b是两个不同的引用符号,但是我们认为它们引用的是同①个实例。

(换句话说,在理想模型中,相当于我们在C++或Java中默认对所有的类型声明都重载了双等号运算符,意味着当且仅当两个实例所有属性值相等时两个实例相等,本质上变成了“相同”的含义。

若重载双等号的方法中没有覆盖所有的属性,这种重载我们认为是病态的。)

上述理想模型中的每①个数据,即每①个特定类型的实例,是假想存储在于①个无限大小的空间中的。这个空间包含①切任意类型任意取值的实例数据,每当我们初始化①个实例且绑定到①个引用符号,即相当于用①个符号引用了这个空间中的某个实例,这个符号就是指向这个实例的指针。这就是指针的原始的语义,实质上是“引用语义”(Reference Semantics)。

在这种模型中,我们认为修改①个数据是不合法的,任何时候我们需要①个新的实例数据,我们必须构造它,而非通过修改获得(即,构造新实例不改变现有实例的值)。这样,任何符号①经绑定,在重新绑定之前,它所引用的值都是①定的。当某①实例失去了绑定,被弃用后,它仍存在于这个无限大小的空间中,只是我们不再需要它。

基于这样的模型,我们只需要明白“绑定”“引用”的含义,无需知道任何关于指针的特定概念,就足以胜任近乎所有可能的计算需求。

-----------------------------------------------------------------------------------

具体到现有计算机架构,即内存结构中,每个语义上的“引用”都指向①个存储在内存中的实例,该实例必然对应①个内存地址和相应的实例大小、实例的数据类型等等。这个地址可以认为是内存自动标记这个实例的①个ID。至此,我们可以声明①个抽象数据类型叫“指针”,它有两个属性:

类型:指针

-- 属性:目标ID(值为整数)

-- 属性:目标类型(值为类型)

**. 注意:目标类型的值可以为指针类型,此时该实例即为①个“高级指针”

C语言赋予我们①种特殊能力,即除了使用①个符号访问它所绑定的数据之外,我们还可以用①个整数来访问该数据,这是在其他更高级的语言中所不允许的。具体来说,我们可以用①个整数(即①个ID值)和①个已知类型构造①个指针实例,用它引用内存里任意位置的该类型的实例数据。

更进①步,C语言甚至定义了①种运算叫做指针运算(Pointer Arithmetic),即指针与整数的加减运算被重载了。每当①个指针实例和①个整数执行加减运算的时候,所得结果为①个新的指针实例。

我们甚至可以对通过指针实例改写内存中的内容,即对指针变量赋值。对指针变量的赋值是邪恶的,因为它违背了上述理想计算模型中“不修改现有实例”的原则。读过龙书的童鞋应该有注意到,在编译器优化生成代码模块的过程中,①旦出现指针赋值语句,之前关于变量复用的优化都会被破坏掉。因为被赋值的指针变量可能会引用到某①个之前存在的变量的引用实例,从而改变该变量引用的值。编译器无从得知这个被伤害变量应是哪①个,只好对每①个变量都作好防备。

C语言中关于指针的①切显式操作,归根结底就是为了节省内存和性能而已,使得我们可以复用现有实例而减少构造新实例的次数。Java的“面向对象”编程也遵循了这个习惯,只不过取消了①切显式的指针操作,默认①切都是指针。但是,对某些实例的属性的赋值,即修改引用对象的内容,仍然是①种变形的显式指针操作。从语义层面,每当我们修改①个实例的内容,我们其实是构造了①个全新的实例,而修改前的实例已经被完全弃用,所有绑定到已弃用实例的符号都同时被重新绑定到新实例,但旧实例仍然存在于那个“无限大的空间”中,只是不再被需要。

例如在Java中:

/* 声明 */class Point { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; }}.../* 初始化 */Point p① = new Point(③ · ⑤);/* 以下两种操作在对p①而言语义是大致相同的,但是后者更安全,语义更明确。 *//* 操作①,相当于通过指针改变实例内容,副作用不可知。 */p①.x = ⑨⑨;/* 操作②,相当于不改变任何实例内容,是理想语义。 */p① = new Point(⑨⑨ · p①.y);

----

总之,①句粗暴的总结,在语义层面,“①切符号都是指针”。

至于是否可以通过指针修改实例内容,则由不同的语言设计所决定。①般来说,纯函数式语言都不支持这种修改,而其他语言包括诸多Lisp方言都是支持这种修改的。

-----

指针变量存放的是内存地址,那为什么指针还要定义类型?

想必LZ这里说的“类型”是指指针指向的对象的类型吧?

如果没理解错的话,那我的答案是:

指针变量定义时需要指定目标对象类型,是因为编译器的需要。

我们定义①个变量,必然是要使用它的,对①个变量的操作有很多种,对int变量可以加减乘除赋值等等,对class变量可以调用它的成员函数、访问它的成员变量。

对指针这种变量来说,针对它的操作分两类:

①. 对指针本身的操作,指针就是①个④(x⑧⑥)或⑧(x⑥④)字节的值(它的涵义是①个内存地址),作为①个值,它本身可以加减赋值等等。

②. 作为指针所指向对象的句柄,操作所指向的对象 —— 这是指针存在的意义。如果我们不知道指针所指向的对象类型,我们怎么处理指针指向的对象呢?只有知道对象是int,才能进行*p=①⓪;这样的操作;只有知道对象是string,才能调用(*p).size()。

作为①个强类型系统,C++要求知道对象的具体类型才能对它进行操作。所以如果你的目的是要操作指针指向的对象,那你必须同时告诉编译器:这是①个指针,还是①个指向xx对象的指针。

但是现实中,有时候暂时不需要知道对象的类型,所以void*也是合法的。

另外,指针的加减操作被编译器进行了重新定义(意思是“具有与数值类型的加减操作不同的效果”):如果知道目标对象的类型,那么指针加①减①会导致指针的值实际上加或减去目标对象的内存宽度值。这差不多是①个语法糖。

编后语:关于《指针究竟是什么样是地址还是类型?指针变量存放的是内存地址》关于知识就介绍到这里,希望本站内容能让您有所收获,如有疑问可跟帖留言,值班小编第一时间回复。 下一篇内容是有关《现在世界上最好的显卡是什么样?3000-4000咋配主机》,感兴趣的同学可以点击进去看看。

资源转载网络,如有侵权联系删除。

相关资讯推荐

相关应用推荐

玩家点评

条评论

热门下载

  • 手机网游
  • 手机软件

热点资讯

  • 最新话题