美文网首页C/C++知识点C语言我爱编程
C语言C++编程新手基础入门学习中 ”.“ 与 ”->“

C语言C++编程新手基础入门学习中 ”.“ 与 ”->“

作者: 小辰带你看世界 | 来源:发表于2018-01-27 14:20 被阅读15次

    这些是C/C++能做的

    服务器开发工程师、人工智能、云计算工程师、信息安全(黑客反黑客)、大数据 、数据平台、嵌入式工程师、流媒体服务器、数据控解、图像处理、音频视频开发工程师、游戏服务器、分布式系统、游戏辅助等

    C语言是面向过程的,而C++是面向对象的

    首先 a->b 的含义是 (*a).b,所以他们是不同的,不过的确->可以用 * 和 . 实现,不需要单独一个运算符。

    从现代的标准化的C语义上来说,->可以用*和.的组合实现。但是,早期的C有一段时间的语义和现代的C的语义不太一样。

    稍微有点汇编的基础的同学可能知道,在机器码和汇编的角度来看,不存在变量,不存在struct这种东西,只存在寄存器和一个叫做内存的大数组。所以变量,是C对内存地址的一个抽象,它代表了一个位置。

    举个栗子,C里面我们写 a = b 其实在汇编的角度来看更像是 *A = *B 其中 A 和 B 各是两个内存地址,是指针。

    好,以上是基本背景。基于这个背景我们讨论一下struct是什么,以及struct的成员是什么。

    假设我们有:

    从现代语义上讲 p 就是一个结构体对象,x 和 y 各是其成员。

    从汇编的语义上讲,p 是一个不完整的地址,或者说,半个地址,再或者说,一个指向的东西是虚构出来的地址。而 x 和 y 各是在 Point 结构中的地址偏移量。也就是说,必须有 p和x 或者 p和y 同时出现,才形成一个完整的地址,单独的一个 p 没有意义。

    早期的C就是在这样的模型上建立的。所以对早期的C而言,*pp 没有意义,你取得了一个struct,而这个struct不能塞在任何一个寄存器里,编译器和CPU都无法表达这个东西。这时候只有 p.x 和 p.y 有意义,它们有真实的地址。

    早期的C就是这样一个看起来怪异的语义,而它更贴近机器的表达。

    所以对早期的C而言,以下的代码是对的:

    而以下代码是错的:

    因为作为这个赋值的目标地址表达式的一部分,*pp,这个中间结果没法直译到机器码。所以对早期的C而言,对pp解引用的操作,必须和取成员的偏移的操作,这两者紧密结合起来变成一个单独的操作,其结果才有意义。

    所以早期的C就发明了->,表示这两个操作紧密结合的操作。于是才能写:pp->x = 1;嗯,这就是它存在的历史原因。而这个历史原因现在已经不重要了,现代的符合标准的C编译器都知道 (*pp).x 和 pp->x 是等价的了。

    说句题外话,C++里面还发明了 .* 和 ->* 这两个运算符(注意 ->* 不是单独的 -> 和 * 并排放的意思),关于为什么要发明这两个运算符,而不能直接说 a ->* b 的意思就是 a ->(*b),请读者们自己动脑想想,并在评论区留言。

    相关文章

      网友评论

        本文标题:C语言C++编程新手基础入门学习中 ”.“ 与 ”->“

        本文链接:https://www.haomeiwen.com/subject/ogunaxtx.html