簡體   English   中英

為什么不能在C中將指針分配給數組?

[英]Why can a pointer not be assigned to an array in C?

我有以下代碼:

int *pa;

int a[3] = {1, 2, 3};

為什么pa = a可以,但不允許a = pa?

主要的區別是a類型仍然是數組,但是在執行pa=a;時它會衰減為指針pa=a; pa現在將指向數組的第一個元素,而不是整個數組本身。 當您執行a=pa它沒有任何意義,因為您嘗試指向一個將3個整數保存為只能指向單個整數的類型的數據類型。

注意:這純粹是概念性的,這不是發生這種情況的實際原因。

我喜歡考慮像OOP和繼承這樣的指針分配。

想象一下int *是一個通用對象。 現在,將int []視為繼承自int *的對象。

如您所見,可以從int []向下轉換為int * ,但不能向上轉換。

好吧,簡單的答案就是語言定義根本不允許它-這是一種設計選擇。

章節

6.5.16賦值運算符
...
約束條件

2賦值運算符的左值應為可修改的左值。

什么是可修改的左值?

6.3.2.1左值,數組和函數指示符

1 左值是具有對象類型或除void之外的不完整類型的表達式; 53)如果左值在評估時未指定對象,則該行為未定義。 當說一個對象具有特定類型時,該類型由用於指定該對象的左值指定。 可修改的左值是不具有數組類型 ,不具有不完整類型,不具有const限定類型的左值 ,並且如果是結構或聯合,則不具有任何成員(包括遞歸地包括任何成員)或const限定類型的所有包含的集合或聯合的元素)。
...
53)名稱“左值”最初來自賦值表達式E1 = E2 ,其中要求左操作數E1是(可修改的)左值。 最好將其表示為對象“定位器值”。 在本國際標准中有時稱為“ rvalue”的內容稱為“表達式的值”。

重點已添加。

C語言中的數組表達式與大多數其他表達式的處理方式有所不同。 丹尼斯·里奇(Dennis Ritchie)撰寫的有關C語言開發的文章對此進行了解釋:

NB存在如此短暫,以至於沒有寫完整的描述。 它提供了類型intchar ,它們的數組以及指向它們的指針,它們以以下形式表示:
\nint i, j; char c, d; int iarray[10]; int ipointer[]; char carray[10]; char cpointer[];\nint i, j; char c, d; int iarray[10]; int ipointer[]; char carray[10]; char cpointer[]; 
數組的語義仍然與B和BCPL中的完全一樣: iarraycarray的聲明創建了動態初始化的單元格,它們的值分別指向10個整數和字符序列的第一個。 ipointercpointer的聲明忽略了大小,以斷言不應自動分配存儲。 在過程中,語言對指針的解釋與對數組變量的解釋相同:指針聲明創建了一個與數組聲明不同的單元,唯一的不同在於,要求程序員分配引用,而不是讓編譯器分配空間和初始化單元格。

存儲在與數組和指針名稱綁定的單元中的值是相應存儲區域的機器地址(以字節為單位)。 因此,通過指針的間接隱含沒有運行時開銷來將指針從字擴展到字節偏移。 另一方面,用於數組下標和指針算術的機器代碼現在取決於數組或指針的類型:計算iarray[i]ipointer+i意味着按引用對象的大小縮放加數i。

這些語義代表了從B的輕松過渡,我嘗試了幾個月。 當我嘗試擴展類型表示法時,尤其是添加結構化(記錄)類型時,問題變得顯而易見。 看來,結構應該以一種直觀的方式映射到機器的內存中,但是在包含數組的結構中,沒有好地方可以存放包含數組基礎的指針,也沒有任何方便的方式來安排它初始化。 例如,早期的Unix系統的目錄條目可能用C描述為
 struct { int inumber; char name[14]; }; 
我希望該結構不僅可以表征抽象對象,而且還可以描述可能從目錄中讀取的位的集合。 編譯器可以在哪里隱藏指向語義所要求name的指針? 即使更抽象地考慮結構,並且可以以某種方式隱藏指針的空間,當分配一個復雜的對象(也許是一個指定包含包含任意深度的結構的數組的結構)時,如何處理正確初始化這些指針的技術問題?

該解決方案構成了無類型BCPL和類型C之間的進化鏈中的關鍵跳躍。它消除了指針在存儲中的實現,當在表達式中提及數組名稱時,導致了指針的創建。 在今天的C語言中仍然存在的規則是,當數組類型的值出現在表達式中時,它們將轉換為指向組成數組的第一個對象的指針。

盡管該語言的語義發生了根本性的變化,但本發明使大多數現有的B代碼能夠繼續工作。 可以很容易地修復幾個為數組名稱分配新值以調整其起源的程序(在B和BCPL中可能,而在C中則毫無意義)。 更重要的是,新語言保留了對數組語義的連貫且可行的解釋(如果不尋常的話),同時為更全面的類型結構開辟了道路。

這是一篇很好的文章,如果您對C的“為什么”感興趣,則非常值得一讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM