取址運算子&
用來取得其運算元的地址。如果運算元 x 的型別為 T,則表示式 &x 的型別是 T 型別指標(指向 T 的指標)。
取址運算子的運算元必須是在記憶體中可定址到的地址。換句話說,該運算子
只能用於函數或物件(例如左值),而不可以用於位欄位,以及那些還未被儲存類修飾符 register 宣告的內容。
當需要初始化指標,以指向某些物件或函數時,需要獲得這些物件或函數的地址:
float x, *ptr;
ptr = &x; // 合法:使得指標ptr指向x
ptr = &(x+1); // 錯誤: (x+1) 不是一個左值
相反地,
當已具有一個指標,並且希望獲取它所參照的物件時,使用間接運算子 *(indirection operator),有時候這會被稱為
解除參照運算子(dereferencing operator)。它的運算元必須是指標型別。如果 ptr 是指標,那麼 *ptr 就是 ptr 所指向的物件或函數。如果 ptr 是一個物件指標,那麼 *ptr 就是一個左值,可以把它(即 *ptr)當作賦值運算子左邊的運算元:
float x, *ptr = &x;
*ptr = 1.7; // 將1.7賦值給變數x
++(*ptr); // 並將變數x的值加1
在這個範例最後的語句中,ptr 的值保持不變,但 x 的值變成 2.7。
如果指標運算元的值不是某個物件或函數的地址,則間接運算子*的操作結果無法確定。
像其他一元運算元一樣,運算子 & 和 * 具有很高的優先順序。運算元的組合方式是從右到左。因此,表示式 ++(*ptr)中的括號是沒有必要的。
運算子 & 和 * 是互補的:如果 x 是一個表示式,用於指定一個物件或一個函數,那麼表示式 *&x 就等於 x。相反地,在形如 &*ptr 的表示式中,這些運算子會互相抵消,表示式的型別與值等效於 ptr。然而,
不管 ptr 是不是左值,&*ptr 都一定不會是左值。