賦值運算子
賦值運算子和複合賦值運算子是二元運算子,它們使用右側的值修改左側的變數。
運算子 | 運算子名稱 | 示例 | 描述 | 等價於 |
---|---|---|---|---|
= | 基本賦值 | a = b | a 變為等於 b | 不適用 |
+= | 加法賦值 | a += b | a 變為等於 a 與 b 的和 | a = a + b |
-= | 減法賦值 | a -= b | a 變為等於 a 減去 b 的差 | a = a - b |
*= | 乘法賦值 | a *= b | a 變為等於 a 與 b 的積 | a = a * b |
/= | 除法賦值 | a /= b | a 變為等於 a 除以 b 的商 | a = a / b |
%= | 取模賦值 | a %= b | a 變為等於 a 除以 b 的餘數 | a = a % b |
&= | 按位與賦值 | a &= b | a 變為等於 a 與 b 的按位與結果 | a = a & b |
|= | 按位或賦值 | a |= b | a 變為等於 a 與 b 的按位或結果 | a = a | b |
^= | 按位異或賦值 | a ^= b | a 變為等於 a 與 b 的按位異或結果 | a = a ^ b |
<<= | 按位左移賦值 | a <<= b | a 變為等於 a 左移 b 位 | a = a << b |
>>= | 按位右移賦值 | a >>= b | a 變為等於 a 右移 b 位 | a = a >> b |
目錄 |
[編輯] 簡單賦值
簡單賦值運算子表示式的形式為
lhs = rhs |
|||||||||
其中
lhs | - | 可修改的左值表示式,型別為任意完整物件型別 |
rhs | - | 表示式,型別為任意可隱式轉換為 lhs 或與 lhs 相容的型別 |
賦值執行從 rhs 的值到 lhs 型別的隱式轉換,然後將 lhs 所指物件中的值替換為 rhs 的轉換值。
賦值還會返回儲存在 lhs
中的相同值(以便諸如 a = b = c 的表示式成為可能)。賦值運算子的值類別是非左值(因此諸如 (a=b)=c 的表示式是無效的)。
rhs 和 lhs 必須滿足以下條件之一
|
(C99 起) |
(自 C23 起) |
[編輯] 注意
如果 rhs 和 lhs 在記憶體中重疊(例如,它們是同一聯合體的成員),則行為未定義,除非重疊精確且型別相容。
儘管陣列不可賦值,但封裝在結構體中的陣列可以賦值給具有相同(或相容)結構體型別的另一個物件。
更新 lhs 的副作用在值計算之後排序,但 lhs 和 rhs 本身的副作用以及運算元的求值,與往常一樣,彼此之間不排序(因此諸如 i=++i; 的表示式是未定義的)
賦值會從浮點表示式中去除額外的範圍和精度(參見 FLT_EVAL_METHOD)。
在 C++ 中,賦值運算子是左值表示式,但在 C 中不是。
#include <stdio.h> int main(void) { // integers int i = 1, j = 2, k = 3; // initialization, not assignment i = j = k; // values of i and j are now 3 // (i = j) = k; // Error: lvalue required printf("%d %d %d\n", i, j, k); // pointers const char c = 'A'; // initialization; not assignment const char *p = &c; // initialization; not assignment const char **cpp = &p; // initialization; not assignment // cpp = &p; // Error: char** is not convertible to const char** *cpp = &c; // OK, char* is convertible to const char* printf("%c \n", **cpp); cpp = 0; // OK, null pointer constant is convertible to any pointer // arrays int arr1[2] = {1,2}, arr2[2] = {3, 4}; // arr1 = arr2; // Error: cannot assign to an array printf("arr1[0]=%d arr1[1]=%d arr2[0]=%d arr2[1]=%d\n", arr1[0], arr1[1], arr2[0], arr2[1]); struct { int arr[2]; } sam1 = { {5, 6} }, sam2 = { {7, 8} }; sam1 = sam2; // OK: can assign arrays wrapped in structs printf("%d %d \n", sam1.arr[0], sam1.arr[1]); }
輸出
3 3 3 A arr1[0]=1 arr1[1]=2 arr2[0]=3 arr2[1]=4 7 8
[編輯] 複合賦值
複合賦值運算子表示式的形式為
lhs op rhs | |||||||||
其中
op | - | 其中之一: *=、/= %=、+= -=、<<=、>>=、&=、^=、|= |
lhs, rhs | - | 具有算術型別的表示式(其中 lhs 可以帶有限定符或原子),但當 op 是 += 或 -= 時除外,它們也接受具有與 + 和 - 相同限制的指標型別 |
表示式 lhs @= rhs 與 lhs =
lhs @ (
rhs )
完全相同,只是 lhs 只求值一次。
如果 lhs 具有原子型別,則該操作行為與單個原子讀-修改-寫操作相同,記憶體順序為 memory_order_seq_cst。 對於整數原子型別,複合賦值 @= 等價於 T1* addr = &lhs; T2 val = rhs; T1 old = *addr; T1 new; do { new = old @ val } while (!atomic_compare_exchange_strong(addr, &old, new); |
(C11 起) |
輸出
10 100 10 50 10 1000 1 0
[編輯] 參考
- C17 標準 (ISO/IEC 9899:2018)
- 6.5.16 賦值運算子 (p: 72-73)
- C11 標準 (ISO/IEC 9899:2011)
- 6.5.16 賦值運算子 (p: 101-104)
- C99 標準 (ISO/IEC 9899:1999)
- 6.5.16 賦值運算子 (p: 91-93)
- C89/C90 標準 (ISO/IEC 9899:1990)
- 3.3.16 賦值運算子
[編輯] 參閱
常見運算子 | ||||||
---|---|---|---|---|---|---|
賦值 | 遞增 遞減 |
算術 | 邏輯 | 比較 | 成員 訪問 |
其他 |
a = b |
++a |
+a |
!a |
a == b |
a[b] |
a(...) |
[編輯] 另請參閱
C++ 文件,關於 賦值運算子
|