c语言中aver是什么意思_C语言中“.”与“->”有什么区别? - Farseerfc的小窩

这篇博客探讨了C语言中结构体成员访问的历史背景。早期C语言中,由于对结构体的处理方式,`*pp`无法直接解引用,必须结合成员访问,因此发明了`->`运算符。现代C编译器理解`(*pp).x`与`pp->x`是等价的。博客还提到了C++中的`.`, `->*`运算符,并留作思考题为何引入这两个运算符。
摘要由CSDN通过智能技术生成

我的回答

首先 a->b

的含義是 (*a).b

,所以他們是不同的,不過的確 ->

可以用 *

和 .

實現,不需要單獨一個運算符。

嗯,我這是說現代的標準化的 C 語義上來說, ->

可以用 *

和 .

的組合實現。

早期的 C 有一段時間的語義和現代的 C 的語義不太一樣。

稍微有點彙編的基礎的同學可能知道,在機器碼和彙編的角度來看,不存在變量,不存在 struct 這種東西,只存在寄存器和一個叫做內存的大數組。

所以變量,是 C 對內存地址的一個抽象,它代表了一個位置。舉個例子,C 裏面我們寫:

a = b

其實在彙編的角度來看更像是

*A = *B

其中 A 和 B 各是兩個內存地址,是指針。

好,以上是基本背景。

基於這個背景我們討論一下 struct 是什麼,以及 struct 的成員是什麼。

假設我們有

struct Point {

int x;

int y;

};

struct Point p;

struct Point *pp = &p;

從現代語義上講 p

就是一個結構體對象, x

和 y

各是其成員,嗯。

從彙編的語義上講, p

是一個不完整的地址,或者說,半個地址,再或者說,一個指向的東西是虛構出來的地址。而 x

和 y

各是在 Point 結構中的地址偏移量。也就是說,必須有 p

和 x

或者 p

和 y

同時出現,才形成一個完整的地址,單獨的一個 p

沒有意義。

早期的 C 就是在這樣的模型上建立的。所以對早期的 C 而言, *pp

沒有意義,你取得了一個 struct ,而這個 struct 不能塞在任何一個寄存器裏,編譯器和 CPU 都無法表達這個東西。

這時候只有 p.x

和 p.y

有意義,它們有真實的地址。

早期的 C 就是這樣一個看起來怪異的語義,而它更貼近機器的表達。

所以對早期的 C 而言,以下的代碼是對的:

p.x = 1;

int *a;

a = &(p.x);

而以下代碼是錯的:

(*pp).x = 1;

因爲作爲這個賦值的目標地址表達式的一部分, *pp

,這個中間結果沒法直譯到機器碼。

所以對早期的 C 而言,對 pp 解引用的操作,必須和取成員的偏移的操作,這兩者緊密結合起來變成一個單獨的操作,其結果纔有意義。

所以早期的 C 就發明了 -> ,表示這兩個操作緊密結合的操作。於是纔能寫:

pp->x = 1;

嗯,這就是它存在的歷史原因。

而這個歷史原因現在已經不重要了,現代的符合標準的 C 編譯器都知道 (*pp).x

和 pp->x

是等價的了。

說句題外話, C++ 裏面還發明了 .*

和 ->*

這兩個運算符(注意 ->*

不是單獨的 ->

和 *

並排放的意思),關於爲什麼要發明這兩個運算符,而不能直接說 a ->* b

的意思就是 a ->(*b)

,這個就作爲課堂作業吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值