C —— 运算符

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。

算术运算符

使用 C 程序对变量进行基本的算术运算,例如:

#include<stdio.h>

int main() {
	int a = 100, b = 200;
	printf("a + b = %d.\n", a + b);
	printf("a - b = %d.\n", a - b);
	printf("a * b = %d.\n", a * b);
	printf("a / b = %d.\n", a / b);
	printf("a %% b = %d.\n", a % b);
	printf("a++   = %d.\n", a++);
	printf("a--   = %d.\n", a--);
	printf("++a   = %d.\n", ++a);
	printf("--a   = %d.\n", --a);
	return 0;
}

执行结果:

a + b = 300.
a - b = -100.
a * b = 20000.
a / b = 0.
a % b = 100.
a++   = 100.
a--   = 101.
++a   = 101.
--a   = 100.

其中 ++-- 也称之为自运算符,分别是自增运算和自减运算。如上例所示,++a 等价于 a = a + 1,同样的,a++ 等价于 a = a + 1。符号 ++ 无论是在变量 a 的前面还是后面,结果都表示将变量 a + 1 后重新赋值给变量 a。

虽然最终变量 a 的值是一样的,但是自增运算符在变量前和变量后得到的表达式的结果是不一样的。如下例所示:

#include<stdio.h>

int main() {
	int a = 10, b;
	b = ++a;
	printf("a = %d, b = %d\n", a, b);
		
	int c = 10, d;
	d = c++;
	printf("c = %d, d = %d\n", c, d);
	return 0;
}

执行结果:

a = 11, b = 11
c = 11, d = 10

从该例中可以知道的是,无论使用 a++ 还是 ++a 最终变量 a 的值都会被自增,结果是没有区别的。区别在于表达式的结果是不一样的,在 c++ 表达式中,表达式的结果(也就是例中的 变量 d )的值是变量 c 自增前的值,而在 ++a 表达式中,表达式的结果(也就是例中的变量 b)的值是变量 a 自增后的值。故而,得到结论是:自运算表达式中,当自运算符作为前缀时,先执行自运算,再将自运算结果作为表达式的结果,当自运算符作为后缀时,先取得变量的值作为表达式的结果,再执行自运算。简记为:

  1. 自运算符作为前缀时:先运算,后取值
  2. 自运算符作为后缀时:先取值,后运算

关系运算符

关系运算符得到的结果一般是布尔类型,值为 true 或者 false,即真或假。在 C 中,一般使用数字 0 表示假,使用数字 1 表示真,当然,使用其他数字如 2,3,4 也可以表示真,但一般不这样做;简记为 非零即真。案例如下:

#include<stdio.h>

int main() {
	int a = 100, b = 200;
	printf("a == b is %d.\n", a == b);
	printf("a != b is %d.\n", a != b);
	printf("a >  b is %d.\n", a > b);
	printf("a <  b is %d.\n", a < b);
	printf("a >= b is %d.\n", a >= b);
	printf("a <= b is %d.\n", a <= b);
	return 0;
}

执行结果:

a == b is 0.
a != b is 1.
a >  b is 0.
a <  b is 1.
a >= b is 0.
a <= b is 1.

三元运算符

类似 Excel 中的 IF 函数,基本格式是: 条件表达式 ? 真值结果 : 假值结果 , 据此,修改上面的关系运算符案例如下:

#include<stdio.h>

int main() {
	int a = 100, b = 200;
	printf("a == b is %s.\n", a == b ? "true" : "false");
	printf("a != b is %s.\n", a != b ? "true" : "false");
	printf("a >  b is %s.\n", a > b ? "true" : "false");
	printf("a <  b is %s.\n", a < b ? "true" : "false");
	printf("a >= b is %s.\n", a >= b ? "true" : "false");
	printf("a <= b is %s.\n", a <= b ? "true" : "false");
	return 0;
}

执行结果:

a == b is false.
a != b is true.
a >  b is false.
a <  b is true.
a >= b is false.
a <= b is true.

逻辑运算符

在 C 中,逻辑运算符主要是 与(&&)或(||)非(!)三种,它主要是对布尔值进行运算。因为在 C 中默认没有定义 boolean 类型,结合上述 非零即真 的思想,可以使用 0 和 1 类模拟布尔运算,案例如下:

#include<stdio.h>

#define true 1
#define false 0

int main() {
	printf("true  && true  is %s.\n", true && true ? "true" : "false");
	printf("true  && false is %s.\n", true && false ? "true" : "false");
	printf("false && true  is %s.\n", false && true ? "true" : "false");
	printf("false && false is %s.\n", false && false ? "true" : "false");
	
	printf("true  || true  is %s.\n", true || true ? "true" : "false");
	printf("true  || false is %s.\n", true || false ? "true" : "false");
	printf("false || true  is %s.\n", false || true ? "true" : "false");
	printf("false || false is %s.\n", false || false ? "true" : "false");
	
	printf("!true          is %s.\n", !true ? "true" : "false");
	printf("!false         is %s.\n", !false ? "true" : "false");
	return 0;
}

执行结果:

true  && true  is true.
true  && false is false.
false && true  is false.
false && false is false.
true  || true  is true.
true  || false is true.
false || true  is true.
false || false is false.
!true          is false.
!false         is true.

位运算符

对变量的二进制值进行按位与(&),按位或(|),按位异或(^),位取取反(~),左移运算(<<)和右移运算(>>)。因为二进制值只有 0 和 1,其运算的真值表参考下表:

PQP & QP | QP ^ Q~P~Q
0000011
0101110
1001101
1111000

在进行位运算的时候,可以将 1 视为 真, 将 0 视为假,可以简记为:

  1. 按位与运算 —— 同真得真,存假得假
  2. 按位或运算 —— 存真得真,全假得假
  3. 按位异或运算 —— 同得假,异得真

简单的位运算案例如下:

#include<stdio.h>

int main() {
	int a = 100, b = 200;
	//   二进制   十进制
	// a 01100100 100
	// b 11001000 200
	// & 01000000 64
	// | 11101100 236
	// ^ 10101100 172
	printf("a & b = %d.\n", a & b);
	printf("a | b = %d.\n", a | b);
	printf("a ^ b = %d.\n", a ^ b);
	printf("~a = %d.\n", ~a);
	printf("~b = %d.\n", ~b);
	return 0;
}

执行结果:

a & b = 64.
a | b = 236.
a ^ b = 172.
~a = -101.
~b = -201.

左移运算和右移运算

将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。为了弄明白这个左移运算,可以尝试将某个数字转换为二进制之后,将其进行左移,然后补零,得到的新的二进制数后重新转换为十进制。这样做比较麻烦,这里使用一个简单的案例来更好地理解左移运算:

#include<stdio.h>

int main() {
	int a = 1;
	printf("%d << 1 = %d\n", a, a << 1);
	printf("%d << 2 = %d\n", a, a << 2);
	printf("%d << 3 = %d\n", a, a << 3);
	printf("%d << 4 = %d\n", a, a << 4);
	printf("%d << 5 = %d\n", a, a << 5);
	return 0;
}

执行结果:

1 << 1 = 2
1 << 2 = 4
1 << 3 = 8
1 << 4 = 16
1 << 5 = 32

可以发现运算结果是有规律的,分别像是 2 的左移数次幂。改变变量 a 的值为7之后重试,结果如下:

7 << 1 = 14
7 << 2 = 28
7 << 3 = 56
7 << 4 = 112
7 << 5 = 224

所以,在左移运算中有:某个整数 n 在执行左移运算的时候,若左移数为 m,则运算结果为 :n × 2m

同理,在右移运算中有:某个整数 n 在执行右移运算的时候,若右移数为 m,则运算结果为 :n ÷ 2m

这两条结论适用于整数,那要是小数呢?修改源程序中的 int 为 double 或者 float,会发现在程序编译的时候提示:invalid operands to binary >>

所以,得到结论:位移运算一般适用于整数类型的运算中

赋值运算符

赋值运算符是 C 语言中最常见的运算符,赋值运算符左边的量的值称之为左值,右边的量的值称之为右值。赋值运算的目的是将右值赋予左边的量。最基本的赋值运算符是 = ,例如:

int a = 10;

这行代码的含义在之前的《变量&常量》有提及,与之类似的还有 +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=, 例如 a += 100; 案例如下:

#include<stdio.h>

int main() {
	int a = 10;
	a += 100;	
	printf("a = %d\n", a);
	return 0;
}

执行结果:

a = 110

由此可知,a += 10 等价于 a = a + 10,同理可得如下结论:

  1. a += 10 等价于 a = a + 10
  2. a -= 10 等价于 a = a - 10
  3. a *= 10 等价于 a = a * 10
  4. a /= 10 等价于 a = a / 10
  5. a %= 10 等价于 a = a % 10
  6. a &= 10 等价于 a = a & 10
  7. a |= 10 等价于 a = a | 10
  8. a ^= 10 等价于 a = a ^ 10
  9. a <<= 10 等价于 a = a << 10
  10. a >>= 10 等价于 a = a << 10

其他运算符

sizeof

sizeof 用于 返回变量或者数据类型的大小,即占用字节的位数。例如:

#include<stdio.h>

int main() {
	int a = 7;
	printf("sizeof(a) is %d.\n", sizeof(a));
	printf("sizeof(int) is %d.\n", sizeof(int));
	printf("sizeof(long) is %d.\n", sizeof(long));
	printf("sizeof(double) is %d.\n", sizeof(double));
	return 0;
}

执行结果:

sizeof(a) is 4.
sizeof(int) is 4.
sizeof(long) is 4.
sizeof(double) is 8.

这里的结果主要取决于机器的字长

逗号 (,)

逗号是一个运算优先级最低的运算符,目前主要出现在赋值表达式和循环结构中。如下例:

#include<stdio.h>

int main() {
	int a = (5, 6), b = (3 + 4, 7 + 8);
	printf("a=%d b=%d\n", a, b);
	for(int i = 1, j = 3; i < 4; i++, j--) {
		printf("i=%d j=%d\n", i, j);
	}
	return 0;
}

执行结果:

a=6 b=15
i=1 j=3
i=2 j=2
i=3 j=1

该程序中,5, 63 + 4, 7 + 8i++, j-- 中的逗号都表示一个运算符。它在目前的程序设计语言中没有太实际的含义,其目的是为了将一个表达式分割为多个子表达式,从而将最后一个表达式的结果作为运算的结果。例如 5, 6 的结果是 6,3 + 4, 7 + 8 的结果是 15,而 i++, j-- 的结果是 j-- 表达式的结果,只不过这里没有变量来接收,可以调整代码使其有一个变量接收运算的结果。如下:

#include<stdio.h>

int main() {
	int a = (5, 6), b = (3 + 4, 7 + 8);
	printf("a=%d b=%d\n", a, b);
	for(int i = 1, j = 3; i < 4; ) {
		int c = (i++, j--);
		printf("i=%d j=%d c=%d\n", i, j, c);
	}
	return 0;
}

执行结果:

a=6 b=15
i=2 j=2 c=3
i=3 j=1 c=2
i=4 j=0 c=1

取址符(&)

该符号用于读取变量的内存地址,例如:

#include<stdio.h>

int main() {
	int a = 100;
	printf("a = %d, &a = %d", a, &a);	
	return 0;
}

执行结果:

a = 100, &a = 2293564

取值符(*)

主要用于指针,读取指针存储的地址值对应的值。例如:

#include<stdio.h>

int main() {
	int a = 100;
	printf("a = %d, &a = %d\n", a, &a);
	int *p = &a;
	printf("p = %d, *p = %d\n", p, *p);
	return 0;
}

执行结果:

a = 100, &a = 2293560
p = 2293560, *p = 100

运算符的优先级

这里以表格的形式展示 C 运算符的优先级,从上往下,优先级依次降低。

运算符运算方向描述
() [] -> . ++ --这里的自运算符作为后缀
+ - ! ~ ++ -- * & sizeof一元运算
* / % + -算数运算
<< >>位移运算
< <= > >= == !=关系运算
& ^ |按位 与,异或,或 运算
&& ||逻辑 与,或 运算
? :三元条件运算
= += -= *= /= %= >>= <<= &= ^= |=赋值运算
,逗号

说明:

  1. () 是优先级最高的运算符,故而,在很多时候,可以使用它修改表达式的优先级。
  2. 自运算符作为前缀和后缀的运算优先级是不一样的,后缀优先级高于前缀。
  3. 在表格的一元运算所在行中,& 用于变量取址,* 用于指针取值,++-- 作为自运算前缀符,~ 是按位取反运算,! 是逻辑非运算符,+- 分别表示的数的正负性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值