[英]Why these two code snippets equivalent to each other (Pointers)
我正在寫一個函數來查找鏈表的長度。 我的問題特定於指針的聲明。
int lengthOfLinkedList(Node *head)
{
Node* current = head;
}
vs.
int lengthOfLinkedList(Node *head)
{
Node* current = NULL;
current = head;
}
因此,這就是我的理解:在第一個示例中,聲明了一個指向Node對象的指針,並且該指針取消引用頭指針的地址。
| 內存地址 <---當前
這不是我想要的。 相反,我想引用該指針,以便可以訪問它指向的節點(這是我在第二個代碼片段中所做的):
|數據| *下一個| <---當前
因此,現在我想到的是,指針在初始化時的行為有所不同-可以在使用('*')運算符進行初始化時直接聲明指向內存地址的指針,但是在初始化后就無法再執行此操作。 真奇怪。
我是對的還是發生了其他事情?
這兩個片段完全相等。 在這兩種情況下, *
都不是解引用運算符(就像它出現在表達式中一樣),但是它只是用於聲明指針的令牌。 換句話說,這里*
邏輯1變為與Node
(如指定類型Node*
,即“指向Node
” 2),而不是與current
。
(對於兩個完全不同的事物(聲明中的指針說明符,表達式3中的一元運算符),相同字符的這種令人困惑的重用來自於以下事實:C擁有“聲明應模仿用法”的思想,因此,由於可以訪問的值您使用*
的指針,甚至用於聲明它們。)
在第一種情況下, current
從頭開始時具有相同的head
值,在第二種情況下,首先將其初始化為NULL
,然后將其更改為具有相同的head
值; 在這兩種情況下,函數結尾處的結果都完全相同。
可悲的是,從語法上講,它與current
一起使用,因為在聲明中,“指針類型說明符”綁定到特定變量; 即,如果您編寫int * ptr1, ptr2;
, ptr1
將為int *
類型,而ptr2
將為純int
。
從右向左讀取時最好理解指針聲明( const char *
:指向字符常量的指針; char * const
:指向字符常量的指針;依此類推); 更一般的聲明(例如函數指針)更加混亂 。
同樣,二進制乘法運算符,但通常沒有混淆(它適用於不同類型,並置於兩個操作數之間)。
在這兩個示例中都沒有取消引用。 兩者都只是將傳遞的指針分配給新變量,然后在函數退出時將其丟棄。
考慮這個順序
int x = 0;
x = 2;
與
int x = 2;
初始化和賦值是不同的 ; 您不是在初始化中取消引用current
版本。 *
僅用於指示current
具有指針類型,僅此而已。
C和C ++聲明語法基於表達式的類型,而不是對象。 例如,如果您有一個指向整數的指針,並且想要獲取該整數值,則必須使用一元*
運算符取消引用該指針:
x = *p;
表達式 *p
的類型是int
,因此可以得出p
的聲明是
int *p;
在聲明中, *
標記僅用於提供其他類型信息; 即, p
是一個指向int
的指針。 重要的是要注意,對於指針聲明T *p
, *
綁定到聲明符,而不是類型說明符。 IOW, T *p;
被解析為T (*p);
。 因此,如果要在單個聲明中聲明多個指針,則必須編寫
T *p, *q, *r;
在這種情況下, p
, q
和r
中的每一個都是指向類型T
指針。
許多C ++程序員都使用T* p;
樣式,因為他們認為強調對象p
的類型更為重要,並且有時它可以使代碼的意圖更加清晰。 但是,它將始終解析為T (*p);
。
為了幫助將指針聲明與取消引用分開,請在取消引用時考慮使用箭頭運算符->
。 例如, *current.data
等效於current->data
; current->next
將為您提供當前下一個指針所指向的節點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.