分配运算符
将右侧操作数的值分配给左侧操作数指定的存储位置,并返回该值。
int x = 5; /* Variable x holds the value 5. Returns 5. */
char y = 'c'; /* Variable y holds the value 99. Returns 99
* (as the character 'c' is represented in the ASCII table with 99).
*/
float z = 1.5; /* variable z holds the value 1.5. Returns 1.5. */
char const* s = "foo"; /* Variable s holds the address of the first character of the string 'foo'. */
一些算术运算具有复合赋值运算符。
a += b /* equal to: a = a + b */
a -= b /* equal to: a = a - b */
a *= b /* equal to: a = a * b */
a /= b /* equal to: a = a / b */
a %= b /* equal to: a = a % b */
a &= b /* equal to: a = a & b */
a |= b /* equal to: a = a | b */
a ^= b /* equal to: a = a ^ b */
a <<= b /* equal to: a = a << b */
a >>= b /* equal to: a = a >> b */
这些复合赋值的一个重要特征是左侧的表达式(a
)仅评估一次。例如,如果 p
是一个指针
*p += 27;
仅引用一次 p
,而以下两次。
*p = *p + 27;
还应注意,诸如 a = b
之类的赋值的结果是所谓的右值。因此,赋值实际上具有一个值,然后可以将该值赋给另一个变量。这允许分配链接在单个语句中设置多个变量。
这个右值可以用在 if
语句(或循环或 switch
语句)的控制表达式中,这些语句保护一些代码对另一个表达式或函数调用的结果。例如:
char *buffer;
if ((buffer = malloc(1024)) != NULL)
{
/* do something with buffer */
free(buffer);
}
else
{
/* report allocation failure */
}
因此,必须注意避免可能导致神秘错误的常见错字。
int a = 2;
/* ... */
if (a = 1)
/* Delete all files on my hard drive */
这将带来灾难性的结果,因为 a = 1
将始终评估为 1
,因此 if
语句的控制表达式将始终为真(请阅读更多有关此常见陷阱的信息 )。作者几乎肯定打算使用等于运算符(==
),如下所示:
int a = 2;
/* ... */
if (a == 1)
/* Delete all files on my hard drive */
运算符相关性
int a, b = 1, c = 2;
a = b = c;
这将 c
分配给 b
,b
将返回 b
,而 b
将分配给 a
。发生这种情况是因为所有赋值运算符都具有正确的关联性,这意味着首先计算表达式中最右边的操作,然后从右向左进行。