操作符在C语言中的妙用
操作符在C语言有着极其重要的地位,比如我们常用的加减乘除以及取模运算等。但其实操作符远远不止这些,主要归为以下几类:
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用以及函数调用和结构成员等
其中主要的操作符优先级顺序如下:
指针最优,单目运算优于双目运算。如正负号。
先算术运算,后移位运算,最后位运算。请特别注意:1 << 3 + 2 & 7等价于 (1 << (3 + 2))&7.
逻辑运算最后结合。(摘自百度百科)
下面对一些重要操作符作一整理:
1.算术操作符&关系操作符&赋值操作符&逻辑操作符
这两类操作符我们接触较多,且用法较为简单,对此不作详解
1.1.复合赋值符
类似于 a+=1;表示a=a+1;前提必须是操作符左边可以容纳右边,即操作符左边必须为变量。
类似的表达还有-=,*=,/=,%=,>>=,<<=,&=,|=,^=
注意:在赋值时尽量不要连续赋值。
1.2.关系操作符
主要有>,<,>=,<=, !=,==,这类操作符主要起判断作用,返回值为1或0.
1.3.逻辑操作符
&&逻辑与;||逻辑或
下面是360一段面试代码
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c =3,d=4; i = a++
&& ++b && d++;
//i = a++||++b||d++;
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}
&&若出现0,后面均不执行;故程序返回1,2,3,4
||若出现真值(即不为0),后面均不执行;故程序返回1,3,3,4
2.移位操作符
<< 左移操作符 >>右移操作符
左移操作符规则:左边抛弃、右边补0
左移操作符相当与乘法。
左移一位相当与x*(2^1);
左移两位相当与x*(2^2),以此类推。
位运算在计算时最快,快于加减乘除
左移操作符规则:
1.逻辑移位 左边用0填充,右边丢弃
2.算术移位 左边用原该值的符号位填充,右边丢弃
右移操作符相当与除法(右移一位相当与x/(2^1),与左移类似)
注意:对于移位运算符,不要移动负数位,这个是标准未定义的。
3.位操作符的妙用
位操作符在日常代码中很少接触,但是它们有着极其重要的作用,常常可以提高程序速度,使问题得以简化。
按位与:&
口诀:见0取0
按位或:|
口诀:见1取1
按位异或:^
口诀:同取0,不同取1
注:它们的操作数必须是整数。
下面来看几道面试题:
例1:
不能创建临时变量(第三个变量),实现两个数的交换
这种题常见的解法是利用c=a+b; a=c-a; b=c-b;
来解决,但是利用位操作就让其变得十分简单。具体代码如下:
#include<stdio.h>
int main()
{
int a = 10; int b = 20;
a = a^b;
b = a^b;
a = a^b;
printf("a = %d b = %d\n",a, b);
return 0;
}
例2:
求出两个数int(32位)的二进制表达中,有多少个位(bit)不同
输入例子:
1999 2299
输出例子:7
解:创建函数用按位异或判断它们之间的不同位(不同为1),输出一个数字len后,再利用按位与求出len中1的个数即可,具体代码如下
#include<stdio.h>
int count_one_bits(unsigned int value)
{
int count = 0;
while (value != 0)
{
count++;
value = value&(value - 1);
}
return count;
}
int diffent_bit(int m,int n)
{
int len = 0;
len=m^n;
return count_one_bits(len);
}
int main()
{
printf("%d\n",diffent_bit(1999,2299));
return 0;
}
例3
一个数组中只有一个数字出现了一次。
其他所有数字都是成对出现的。
请找出这个数字。
解:采用&操作即可
#include<stdio.h>
int main()
{
int arr[11] = { 0, 1, 2, 3, 4, 9, 4, 3, 2, 1, 0 };
int i=0;
int len = sizeof (arr) / sizeof(arr[0]);
for (i = 1; i < len; i++)
{
arr[0] = arr[0] ^ arr[i];
}
printf("单独的数字为:%d\n", arr[0]);
return 0;
}
4.单目操作符&三目操作符(条件操作符)
4.1.主要的单目操作符有
! 逻辑反操作
sizeof 操作数的类型长度(以字节为单位)
sizeof可以求变量(类型)所占空间的大小
注意:所有类型的指针均为4个字节!4个字节!4个字节!
& 取地址
~ 对一个数的二进制按位取反 前置
++,–
4.2.三目操作符
exp1 ? exp2 : exp3
主要起到选择作用
将以下代码改为三目操作符为
if (a > 5)
b = 3;
else
b = -3;
a > 5 ? b = 3 : b = -3
5.逗号表达式
主要形式为:
exp1, exp2, exp3, …expN
从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
有如下代码:
#include<stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d\n", c);
return 0;
}
故输出c的值为13.
6.操作符的属性
- 操作符的优先级
- 操作符的结合性
- 是否控制求值顺序
有如下代码:
int main()
{
int i = 10;
i =i-- - --i * ( i= -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
这样的代码无任何意义。
操作符的优先级只能决定自减–的运算在+的运算的前面,但是我们并没有办法得知,+操作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。
操作符在C语言有着极其重要的地位,用好操作符,写出的代码往往会有让人意想不到,让别人眼前一亮的效果。