今天的文章一起来看看C语言的运算符,而和C语言运算符直接相关的一个问题就是类型转换。下面先来看看C语言有哪些运算符。
算数运算符
算数运算符包括:加(+),减(-),乘(*),除(/),取余(%),自增(++),自减(--),下面上代码,直接看例子。
#include <stdio.h> int main(void) { int a = 10; int b = 2; 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, ++a = %d\n", a++, ++a); printf("b-- = %d, --b = %d\n", b--, --b); int c = a++; int d = a--; printf("c = %d\n", c); printf("d = %d\n", d); return 0; }
运行结果:
a + b = 12
a - b = 8
a * b = 20
a / b = 5
a % b = 0
a++ = 11, ++a = 12
b-- = 1, --b = 0
c = 12
d = 13
需要说明的有以下几点:
%运算符只可以用于两个整型;
a++和++a在打印时没有差别,但是将其赋值给变量时,存在差别,如上例中的c和d,a++是先将a赋值给变量,之后才会做自增;++a则是自增后将值赋值给变量。--运算符与++运算符类似。
关系运算符
关系运算符用来比较两个数的大小,包括:等于(==),不等于(!=),大于(>),大于等于(>=),小于(<),小于等于(<=),看一下例子。
#include <stdio.h> int main(void) { int a = 1; int b = 2; 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 >= b: %d\n", a >= b); return 0; }运行结果:
a == b: 0
a != b: 1
a < b: 1
a <= b: 1
a > b: 0
a >= b: 0
可以看到,C语言中使用0和1分别代表false和true。
逻辑运算符
逻辑运算符包括:逻辑与(&&),逻辑或(||),逻辑非(!)。
#include <stdio.h> int main(void) { int a = 1; int b = 2; int c = 3; printf("a > b && c > b: %d\n", a > b && c > b); printf("a > b || c > b: %d\n", a > b || c > b); printf("!(a > b): %d\n", !(a > b)); return 0; }
运行结果:
a > b && c > b: 0
a > b || c > b: 1
!(a > b): 1
需要说明的是,逻辑运算符存在短路的机制,比如上面的第一句printf,由于a>b为false,此时逻辑与已经不可能为true,所以后面的c>b将不会运行,也就是说逻辑与会被第一个为false的条件表达式所阻断;同理,对于逻辑或,如果前面的条件表达式已经为true,则无论后面的条件表达式为true或者false都对结果无关紧要了,逻辑或将会执行到第一个为true的条件表达式。
位运算符
位运算符操作整型的位,包括:按位与(&),按位或(|),异或(^),按位取反(~),左移(<<),右移(>>)。
#include <stdio.h> int main(void) { int a = 1; int b = 4; printf("a = 0x%08x\n", a); printf("b = 0x%08x\n", b); printf("a & b: 0x%08x\n", a & b); printf("a | b: 0x%08x\n", a | b); printf("a ^ b: 0x%08x\n", a ^ b); printf("~a: 0x%08x\n", ~a); printf("a << 2: 0x%08x\n", a << 2); printf("a >> 1: 0x%08x\n", a >> 1); printf("a | (1 << 2): 0x%08x\n", a | (1 << 2)); printf("b & ~(1 << 2): 0x%08x\n", b & ~(1 << 2)); return 0; }
运行结果:
a = 0x00000001
b = 0x00000004
a & b: 0x00000000
a | b: 0x00000005
a ^ b: 0x00000005
~a: 0xfffffffe
a << 2: 0x00000004
a >> 1: 0x00000000
a | (1 << 2): 0x00000005
b & ~(1 << 2): 0x00000000
需要说明以下几点:
左移运算,最高位会移出,低位补0;
右移运算,低位移出,最高位为1,则为1,为0,则为0,即保留符号位;
最后两条printf语句,用来演示如何给一个数的第2位置位为1和如何清除一个数第2位的1。
赋值运算符
主要包括=, +=,-=,*=,/=,%=,<<=,>>=,&=,|=,^=,除了=运算符,其他的都是结合了其他运算符的功能,比如a += 1,就是将a和1相加,再把结果赋值给a,这里不再赘述。
类型转换
C语言是强类型语言,不同类型的数据之间进行运算会进行类型的转换,转换方式主要有两种,强制类型转换和隐式类型转换。
强制类型转换是在编码时通过显式编写代码,实现的类型转换;隐式类型转换则是C语言编译器自动为我们进行的类型转换,总的原则是
如果表达式中的数据属于同一个大类型,比如都是整型,则数据统一向表达式中宽度最大的转换,如int向long转换,有符号类型还会向无符号类型转换,如int向unsigned int转换;
整型和浮点型运算,整型会转换为浮点型。
强制将浮点型转换为整型,浮点型小数部分丢失。
看一个简单的例子
#include <stdio.h> int main(void) { int a = 1; float b = 2.2; long c = 12; printf("a + c = %ld\n", a + c); printf("a + b = %f\n", a + b); printf("a + (int)b = %d\n", a + (int)b); return 0; }
运行结果:
a + c = 13
a + b = 3.200000
a + (int)b = 3