參考(計算機科學)

計算機編程中,參考是一個值,它使程序能夠在計算機內存或其他一些存儲設備中間接訪問特定數據(例如變量的值或記錄) 。據說參考文獻是基準,訪問基準稱為取消參考。引用與基準本身不同。

參考是一種抽像數據類型,可以通過多種方式實現。通常,引用是指存儲在給定係統上的內存中的數據,其內部值是數據的內存地址,即作為指針實現參考。因此,通常會說參考要“指向”數據。其他實現包括基準地址和一些固定的“基礎”地址之間的偏移(差異),查找操作中使用的索引或標識符,用於數組表格,操作系統句柄,存儲設備上的物理地址或網絡地址,例如URL

正式代表

參考r是一個接收一個操作的R )的值,它產生一個值。通常,該參考是鍵入的,因此它返回特定類型的值,例如:

interface Reference<T> {
  T value();
}

通常,引用還可以接受分配操作商店RX ),這意味著它是一個抽像變量

使用

參考文獻被廣泛用於編程中,尤其是將大型或可變數據作為參數傳遞給程序,或在各種用途之間共享此類數據。特別是,引用可能指向包含對其他數據的引用的變量或記錄。這個想法是間接解決的基礎,也是許多鏈接的數據結構(例如鏈接列表)的基礎。參考文獻在可以存儲對象,分配方式以及如何在代碼區域之間傳遞的位置增加了靈活性。只要可以訪問對數據的引用,就可以通過它訪問數據,並且不必移動數據本身。它們還使不同代碼區域之間的數據共享更加容易;每個人都對其進行引用。

參考文獻可能會在程序中引起重大復雜性,部分原因是懸掛狂野參考的可能性,部分原因是參考文獻的數據拓撲有向圖,其分析可能非常複雜。但是,由於缺乏指針算術,參考文獻仍然比指針更簡單。

引用的機制,如果在實施方面有所不同,則是幾乎所有現代編程語言共有的基本編程功能。甚至某些不支持參考文獻的語言也具有某些內部或隱式用途。例如,可以通過明確或隱式使用引用來實現撥打參考通話約定的調用。

例子

指針是最原始的參考類型。由於它們與基礎硬件的親密關係,它們是最強大,最有效的參考類型之一。但是,由於這種關係,指針需要對程序員的記憶體系結構細節有深入的了解。由於Pointers存儲了存儲位置的地址,而不是直接的價值,因此不適當使用指針可能會導致程序中的不確定行為,尤其是由於懸掛的指針野生指針智能指針不透明的數據結構,其作用像指針,但只能通過特定方法訪問。

手柄是抽象參考,可以用各種方式表示。一個常見的示例是用於抽象文件內容的文件手柄C標準I/O庫中的文件數據結構)。它通常代表文件本身,例如在文件上請求鎖定時,以及文件內容中的特定位置,就像讀取文件時一樣。

分佈式計算中,參考可能包含的不僅僅是地址或標識符。它還可能包括用於定位和訪問引用對象的網絡協議的嵌入式規範,信息的編碼或序列化方式。因此,例如,可以將遠程Web服務的WSDL描述視為一種參考形式。它包括如何找到和綁定到特定的Web服務的完整規範。對實時分佈式對象的引用是另一個示例:它是如何構造稱為代理的小軟件組件的完整規範,該組件隨後將參與點對點互動,並且本地機器可以通過該組件訪問僅作為弱一致的消息流而復製或存在的數據。在所有這些情況下,參考文獻包括有關如何訪問數據的完整指令或食譜;從這個意義上講,它具有與內存中的標識符或地址相同的目的。

如果我們有一組鍵k和一組數據對象d ,則從kd∪ { null }的任何定義明確的(單值)函數定義了一種參考類型,其中null是鍵的圖像,沒有引用對任何有意義的事物。

這種函數的替代表示是稱為可及圖的有向圖。在這裡,每個基準由頂點表示,如果u的基準是指v中的基準,則從u到v有一個邊緣。最大級別是一個。這些圖在垃圾收集中很有價值,可以用來將它們與無法訪問的對象分開。

外部和內部存儲

在許多數據結構中,大型複雜的對象由較小的對象組成。這些對象通常以兩種方式存儲:

  1. 使用內部存儲,較小對象的內容存儲在較大的對象內。
  2. 使用外部存儲,較小的對象將在自己的位置分配,較大的對象僅存儲對它們的引用。

內部存儲通常更有效,因為參考文獻和動態分配元數據的空間成本,以及與取消參考並分配較小對象的內存相關的時間成本。內部存儲還通過將同一大對象的不同部分保持在內存中,從而增強了參考的位置。但是,在各種情況下,首選外部存儲:

  • 如果數據結構是遞歸的,則意味著它可能包含自身。這不能以內部方式表示。
  • 如果將較大的對象存儲在具有有限空間的區域(例如堆棧)中,那麼我們可以通過將大型組件對象存儲在另一個內存區域並使用參考引用來防止耗盡存儲空間。
  • 如果較小的物體的尺寸變化,調整較大對象的大小通常不方便或昂貴,以便它仍然可以包含它們。
  • 參考通常更容易使用,並更好地適應新的要求。

某些語言,例如JavaSmallTalkPythonScheme ,不支持內部存儲。在這些語言中,所有對像都是通過參考均勻訪問的。

語言支持

集會

彙編語言中,通常使用原始內存地址或索引中表達參考。這些工作,但使用有些棘手,因為一個地址對其指向的價值一無所知,甚至不是它的數量或如何解釋它。此類信息在程序邏輯中編碼。結果是在不正確的程序中可能會發生誤解,從而導致錯誤。

Lisp

最早的不透明引用之一是LISP語言CONS細胞的參考文獻,它只是包含對其他LISP對象(包括可能其他CONS)細胞的兩個參考的記錄。這種簡單的結構最常用於構建單個鏈接的列表,但也可以用於構建簡單的二進制樹和所謂的“點點列表”,該列表不是終止的,而不是以空引用,而是值。

C/C ++

指針仍然是當今最受歡迎的參考類型之一。它類似於原始地址的彙編表示形式,只是它帶有靜態數據類型,該數據類型可以在編譯時使用,以確保其指的數據不會誤解。但是,由於C具有薄弱的類型系統,該系統可以使用鑄件(各種指針類型之間的明確轉換以及指針類型和整數之間的明確轉換),因此,如果更困難,誤解仍然是可能的。它的繼任者C ++試圖通過新的Cast Operators提高指針的類型安全性,這是一種參考類型&,以及其標準庫中的智能指針,但仍然保留了規避這些安全機制以兼容的能力。

Fortran

Fortran沒有明確的參考表示,但確實在其逐個引用呼叫語義中隱含地使用它們。最好將fortran引用視為另一個對象的別名,例如標量變量或數組的行或列。沒有語法可以直接取消參考或操縱參考內容的內容。 fortran參考可能為零。與其他語言一樣,這些參考文獻有助於處理動態結構,例如鍊接列表,排隊和樹。

面向對象的語言

許多面向對象的語言,例如EiffelJavaC#Visual Basic採用了更不透明的參考類型,通常稱為參考。這些參考文獻具有諸如c指示器的類型,指示如何解釋其引用的數據,但是它們是類型的,因為它們不能解釋為原始地址,並且不允許使用不安全的轉換。引用廣泛用於訪問和分配對象。引用也用於功能/方法調用或消息傳遞中,並且參考計數經常用於執行未使用對象的垃圾收集

功能性語言

標準MLOCAML和許多其他功能語言中,大多數值都是持久的:不能通過分配來修改它們。可分配的“參考單元”提供可變變量,可以修改的數據。這樣的參考單元可以容納任何值,因此被給予多態性類型α ref, 在哪裡α將用指向的值的類型替換。這些可變的參考可以指向其一生中不同的對象。例如,這允許構建循環數據結構。參考單元在功能上等同於長度1的可突變陣列。

為了保留安全性和有效的實現,參考文獻不能在ML中進行類型鑄造,也不能執行指針算術。在功能範式中,使用其他設施(例如功能強大的代數數據類型機制)代表使用指針的許多結構。然後,程序員能夠在編程時享受某些屬性(例如不變性的保證),即使編譯器經常在“引擎蓋下”使用機器指針。

perl/php

Perl支持硬引用,這些引用與其他語言相似,符號引用,這些引用僅是包含變量名稱的字符串值。當對不硬引用的值被刪除時,Perl將其視為符號引用,並以值給出的名稱給出變量。 PHP的形式具有類似的功能$$var句法。

Python

Python包括廣泛的參考。通常,程序員使用id(var)訪問變量的參考地址var。 Python中的參考比C ++或其他編程語言更為複雜。

常數(例如,整數2)是python中的對象,因此具有固定地址的引用。當程序員打電話時a = 2,該程序為輔音創造一個內存空間2並安排對它的參考。然後該程序鏈接了a地址2,這表明更改數值變量的值會改變其參考。而在可變類型中(例如,list類型),值更改不會改變變量的參考。

當變量作為函數參數傳遞時,該函數默認情況下獲取對其的引用,而不是其值。對於可變類型,這會導致原始變量易於修改;對於不可變的類型,修改其在函數中的值將導致函數中的臨時變量參考被修改為其他地方,因此不會導致更改原始變量。

也可以看看