赋值运算符

赋值运算符

赋值及复合赋值运算符是二元运算符,它们用在其右侧的值修改在其左侧的变量。

运算符

运算符名

示例

描述

等价

=

基本赋值

a = b

a 变得等于 b

N/A

+=

加法赋值

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 的值到 rhs 类型的隐式转换,然后用 rhs 转换后的值替换 lhs 所指代对象中的值。

赋值亦返回存储于 lhs 中的相同值(故如 a = b = c 的表达式是可行的)。赋值运算符的值类别是非左值(故如 (a=b)=c 的表达式非法)。

rhs 与 lhs 必须满足下列条件之一:

lhs 与 rhs 拥有兼容的 struct 或 union 类型,或……

rhs 必须可隐式转换成 lhs ,这表示

lhs 与 rhs 均拥有算术类型,此情况下 lhs 可为volatile 限定或原子的

lhs 与 rhs 均拥有指向兼容类型的指针类型,或其中一个指针是指向 void 的指针,而转换不为被指向类型添加限定符。 lhs 可以为 volatile 或 restrict 限定,或原子的。

lhs 是指针(可以有限定或是原子的),而 rhs 是空指针常量,如 NULL 。

lhs 拥有类型 _Bool(可以有限定或是原子的)而 rhs 是指针 。

注意

若 rhs 与 lhs 在内存中重叠(例如它们是同一联合体的成员),则行为未定义,除非重叠是准确的且两者类型兼容。

尽管数组不可赋值,但包裹在结构体内的数组可以赋值给另一个相同(或兼容)的结构体类型。

更新 lhs 的副效应后序于值计算,但 lhs 和 rhs 自己和运算数的求值不是,与通常一样,它们相对于彼此是不定序的(故如 i=++i 的表达式是未定义的)

赋值会剥除浮点表达式的额外范围和精度(见 FLT_EVAL_METHOD )。

C++ 中,赋值运算符是左值表达式,而 C 中不是

运行此代码

#include

int main(void)

{

const char **cpp;

char *p;

const char c = 'A';

// cpp = &p; // 错误: char** 不能转换为 const char**

*cpp = &c; // OK : char* 能转换为 const char*

*p = 0; // OK :空指针常量能转换为任何指针

int arr1[2] = {1,2}, arr2[2] = {3, 4};

// arr1 = arr2; // 错误:不能通过数组赋值

struct s {

int arr[2]; // 包装于结构体中的数组

} sam1 = {5, 6}, sam2 = {7, 8};

sam1 = sam2; // OK :能赋值包装于结构体中的数组

printf("%d %d \n",sam1.arr[0],sam1.arr[1]);

}

输出:

7 8

复合赋值

复合赋值运算符表达式拥有形式

lhs op rhs

其中

op

-

one of *=, /= %=, += -=, <<=, >>=, &=, ^=, |=

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 起)

本节未完成原因:暂无示例

引用

C11 standard (ISO/IEC 9899:2011):

6.5.16 Assignment operators (p: 101-104)

C99 standard (ISO/IEC 9899:1999):

6.5.16 Assignment operators (p: 91-93)

C89/C90 standard (ISO/IEC 9899:1990):

3.3.16 Assignment operators

参阅

运算符优先级

常用运算符

赋值

自增自减

算术

逻辑

比较

成员访问

其他

a = b

a += b

a -= b

a *= b

a /= b

a %= b

a &= b

a |= b

a ^= b

a <<= b

a >>= b

++a

--a

a++

a--

+a

-a

a + b

a - b

a * b

a / b

a % b

~a

a & b

a | b

a ^ b

a << b

a >> b

!a

a && b

a || b

a == b

a != b

a < b

a > b

a <= b

a >= b

a[b]

*a

&a

a->b

a.b

a(...)

a, b

(type) a

? :

sizeof

_Alignof (C11 起)

相关推荐

自己动手,快速制作自己的照片书! 365体育是正规的吗

自己动手,快速制作自己的照片书!

📅 06-29 👁️ 4675
白娘子盗仙草,千年的灵芝上哪里找? beat365登录平台

白娘子盗仙草,千年的灵芝上哪里找?

📅 01-25 👁️ 4335