這不是典型的討厭指針的問題,而是一個非常有趣的問題。
指針是一個非常強大的概念,但它就是這樣:一個概念。那為什麼 C 編譯器要發明這樣一個專門用來指標的獨立邏輯和語法呢?
不要誤會我的意思,我喜歡指針給我們提供的機會及其當前的語法。它們是絕對重要的功能,實現了動態資料結構、物件和類別、多執行緒記憶體共享、物件可變性、低冗餘值重複等的演變。
但如果你想像 C 的發明事件,今天的指針似乎是一個比直觀的第一個概念更令人印象深刻的想法。讓我們更深入地了解我的意思。
如果你看一下指標的結構,它基本上是一個 unsigned long (又名 4[32 位元系統] 或記憶體中的 8 個位元組)。將指針與無符號長整型分開的東西是指針特定的功能。
指標有自己的聲明語法和屬性運算子:解引用器。
int a = 5; int *ptr = &a; //declaration int value = *ptr; //dereference
但是讓我們想像一下,這從未被發明過。如果解除引用功能僅與任何整數類型相關聯,則以下內容將很容易實現:
int a = 5; unsigned long adress = &a; int value = *adress;
在這種情況下,你甚至可以這樣做:
int firstIntInMemory = *(0); //manually dereferences (4bytes at) adress 0`
說到解析器,這完全不是一個衝突的語法,因為作為解引用器的星號是一元運算符,而作為算術乘法器的星號始終是二元運算符。
正如我上面所描述的,這個虛構的解引用運算子實際上是指標概念的原始本質。將其與當前的實際實現進行比較,使得思考這個核心問題變得非常有趣。本來可以有很多結果。
指針算術唯一特別的事情是將類型大小與計算結合。當我有一個數組,並且想要取得第二個元素時,我只需向指標加 1 即可。如果它是一個 int 指針,這實際上會隱式地將值 4 添加到地址(如果您的系統上 sizeof(int) == 4):
int arr[5] = {1,2,3,4,5}; int second = *(arr 1);
但要說實話,如果您直觀地思考內存,以下內容實際上更符合邏輯:
int arr[5] = {1,2,3,4,5}; int second = *(arr sizeof(int));
這只是標準的整數算術。如果你這樣看,就根本沒有理由發明指針算術。
當然,「*」文法讓預期用途更加清晰。如果你看到它,你會立即知道這個變數用於記憶體操作。此外,每個記憶體操作庫函數都是為指標設計的。
但是,如果它從未被發明,而是我們擁有這些可解引用的無符號長整型,人們就會想出設計和命名約定,例如附加帶有“_p”後綴的指標變數標識符。內存操作庫將圍繞此發展。
所以說真的,如果你想一想,如果指針從未作為語言的一個特性而被發明的話,C 可能會像現在一樣生存下來。它們只是由程式設計師作為一個概念發明的,其工作方式與目前存在的方式相同。
我發現這是一個有趣的故事,值得深入研究。
為什麼C要發明指針?
這是否正是我們所期望的原因:一致性、清晰度和安全性,防止誤用去引用?
或者是否有比我在這篇文章中介紹指標的方式更深層的原因和更複雜的邏輯,這使得它們實際上比對通用整數執行相同的操作更加有效?
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3