操作符
1、双目操作符
双目操作符的操作对象对两个。如加法,只有a+b,没有a+,也没有+a。
操作符 | + | - | * | / | % | << | >> | & | | | ^ | = |
---|---|---|---|---|---|---|---|---|---|---|---|
意义 | 加 | 减 | 乘 | 除 | 取模 | 左移 | 右移 | 按位与 | 按位或 | 按位异或 | 赋值 |
备注 | 注1 | 注2 | 注3 | 注4 |
注1
C语言中,除法有整数除法和小数除法。
整数除法:
代码1:
#include<stdio.h>
int main(){
int i1=21/10;
int i2=25/10;
int i3=29/10;
printf("i1 = %d ;i2 = %d; i3 = %d\n",i1,i2,i3);
return 0;
}
代码2:
#include<stdio.h>
int main(){
int i1=(-1*21)/10;
int i2=(-1*25)/10;
int i3=(-1*29)/10;
printf("i1 = %d ;i2 = %d; i3 = %d\n",i1,i2,i3);
return 0;
}
代码1的运行结果是:i1 = 2 ;i2 = 2; i3 = 2。代码2的运行结果是i1 = -2 ;i2 = -2; i3 = -2。这就很有意思了。一般而言骂我们对小数向整数近似有3种方法:四舍五入,向下取整和向上取整。而这三对C语言来说哪个都不适用。C语言直接是把小数剔除,只留整数。
小数除法:
除数或被除数种只要有一个是小数那就执行小数除法。如float a = 21/10.0;会得出a的值为2.1而不是像整除除法一样得到2。
注2:
int a = 7 % 3的意思是把7除以3的余数1赋值给a。
注3:
左移和右移都是对二进制进行操作,左移可以简单的认为是整数除法除以2,右移可以简单的认为乘以2。
注4:
按位操作是将两个二进制数各位对其,后每一位与相对应的为进行逻辑运算。如c = 24 & 21,运算如下表所示:
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
---|---|---|---|---|---|---|---|---|
24 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
21 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
c = 24 & 21 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
还有其他双目操作符号,比如+=。a+=1的意思是a=a+1。详见下表:
操作符 | += | -= | *= | /= | <<= | >>= | &= | |= | ^= |
---|---|---|---|---|---|---|---|---|---|
例 | a+=b | a-=b | a*=b | a/=b | a<<=b | a>>=b | a&=b | a|=b | a^=b |
意思 | a=a+b | a=a-b | a=a*b | a=a/b | a=a<<b | a=a>>b | a=a&b | a=a|b | a=a^b |
2、单目操作符
只有一个操作元素的操作符。
操作符 | ! | - | + | & | * | sizeof | ~ | ++ | -- | (变量类型) |
---|---|---|---|---|---|---|---|---|---|---|
意义 | 取非 | 去负值 | 取正值 | 取地址 | 取地址中的值 | 计算类型/变量的大小 | 按位取反,具体参考数电 | 强制转换 | ||
备注 | 多用于真假判断 | 不是减 | 不是加 | 不是位与 | 不是成 | 注2 | 如~(101)->010 | 注3 | 如(int)a |
注1:
对于+、-、*、/,如何区分它们是单目操作还是双目操作,主要是看它们前面有没有要操作的元素。如 a = -12 + 5,a = *p。其中的-和就是单目操作。
可以让单目操作符紧跟着操作元素,双目操作符的操作符与操作元素之间用一个空格隔开;或者是用小括号将单目操作的操作符和操作元素一起括起来。比如int a = ( *(p + sizeof(int)) ) * 9;,这里的第一个*是单目操作取地址,第二个*是双目操作乘法。翻译一下语句的意思是int a = p[1] * 9。
注2:
sizeof可以用于计算类型或变量的大小,这里的大小指的是其所占空间的大小。用法是sizeof(a)或sizeof a。但不能sizeof int,要用sizeof(int)。注意sizeof()并不是一个函数。
注3:
代码1:
#include<stdio.h>
int main(){
int a = 5;
int b;
int c;
printf("%d\n",a);
b = a++;
printf("%d\n",a);
c = ++a;
printf("b:%d;\tc:%d\n",b,c);
printf("b:%d;\tc:%d\n",b,c);
return 0;
}
代码2:
#include<stdio.h>
void a_plusplus(){
int a = 5;
a++;
printf("a++\n");
printf("%d\n",a);
printf("%d\n",a);
}
void plusplus_a(){
int a = 5;
++a;
printf("++a\n");
printf("%d\n",a);
printf("%d\n",a);
}
int main(){
a_plusplus()
plusplus_a()
return 0;
}
代码3:
#include<stdio.h>
void a_plusplus(){
int a = 5;
printf("a++\n");
printf("%d\n",a++);
printf("%d\n",a);
}
void plusplus_a(){
int a = 5;
printf("++a\n");
printf("%d\n",++a);
printf("%d\n",a);
}
int main(){
a_plusplus();
plusplus_a();
return 0;
}
代码1的运行结果:
5
6
b:5 c:7
b:5 c:7
代码2的运行结果:
a++
6
6
++a
6
6
代码3的运行结果:
a++
5
6
++a
6
6
可见,a++和++a单独成句时,和a=a+1没有区别,但到赋值和套进printf内时,就产生了区别。具体可以概括成:a++是先把a在这句话中用出去,再在这句话下面执行a=a+1。而++a则是先在执行此句代码之前执行一遍a=a+1,再执行改代码。如b=a++;可以视作b=a;a=a+1;的复合,c=++a可以视作a=a+1;c=a的复合。
个人的碎碎念:依稀记得以前看的书。书上专门区分a++和++a的区别,好像是看printf("%d",++a);和printf("%d",a++)的输出结果来着。现在看来这么写代码纯纯的脑抽。这玩意儿完全可以分两行写的,多写一行又不影响功能,还增加程序可读性,还不存在不同编译器执行不同标准从而导致不同编译器跑出来结果可能不一样的情况,谁吃饱没事干写这么个抽象的玩意儿啊。只用a++单独成句代替a=a+1不挺好嘛。
3、关系操作符
操作符 | == | != | > | >= | < | <= |
---|---|---|---|---|---|---|
意思 | 判断是否相等 | 判断是否不相等 | 判断左边是否大于右边 | 判断左边是否大于等于右边 | 判断左边是否小于右边 | 判断左边是否小于等于右边 |
备注 | 若判断为真,则值为1(TRUE),否则值0(FALSE)。基本用于选择、循环的条件语句中。如if(a==1),while(a<10) |
4、逻辑操作符
操作符 | && | || |
---|---|---|
意义 | 逻辑与 | 逻辑或 |
备注 | 常见于条件语句中,布尔值运算或许也能见到 |
5、条件操作符
操作符 | 条件?语句1:语句2 |
---|---|
意义 | 条件为真,用语句1代替这个表达,否则用语句2代替这个表达 |
备注 | max = a>b ? a : b;意思是若a>b,则max = a,否则max = b |
6、其他操作符
除了上述操作符,还有逗号操作符(代码1,代码2,...,代码n),.,->。其中.和->是和指针、结构体之类相关的,逗号操作符说明如下。
int a = (代码1,代码2,...,代码n);等同于:
代码1;
代码2;
...
代码(n-1);
int a = 代码n;