大家好哦!晚间时间,有到了写博客的时间.今天简单的复习下操作符,下面进入正题~
操作符的分类
话不多说,大家看图:


以上的操作符,我们已经讲过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单⽬操作符.下面在学习一部分.操作符中有⼀些操作符和⼆进制有关系,但是二进制部分比较基础,就不过多写了.但是在这里补充下原码、反码、补码这部分内容.
原码、反码、补码
整数 的2进制表方法法有三种,即原码、反码和补码 . 有符号整数 的三种表⽰⽅法均有符号位 和数值位 两部分,2进制序列中,最高位的1位是被当做符号位,剩余的都是数值位。 符号位都是⽤0表⽰"正",⽤1表⽰"负".
正整数的原、反、补码都相同。
负整数
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
补码得到原码也是可以使⽤:取反,+1的操作。对于整型来说:内存中其实存放的是补码.
移位操作符
<<左移操作符,>> 右移操作符.
注:移位操作符的操作数只能是整数。对于移位运算符,不要移动负数位,这个是标准未定义的.不会对操作数有影响.
左移操作符
移位规则: 左边抛弃、右边补0.每左移一位返回值 就会变为左移前二倍.左移的那个数之不会变.


右移操作符
右移运算分两种:(对于正整数来说二者没有什么区别)
**1. 逻辑右移:**左边⽤0填充,右边丢弃
2. 算术右移: 左边⽤原该值的符号位填充,右边丢弃(在vs下用的是这一种移位方法).

位操作符:&、|、^、~
位操作符有:
& //按位与 同为1才返回1
| //按位或 有1就返回1
^ //按位异或 相异为1,相同为0
~ //按位取反 1变0,0变1
注:他们的操作数必须是整数. 不会对操作数有影响.
使用方法见代码
cpp
int main()
{
int a = -3;
int b = 5;
printf("%d\n", a & b);
printf("%d\n", a | b);
printf("%d\n", a ^ b);
printf("%d\n", 0);
printf("%d\n", a);
return 0;
}
⼀道变态的⾯试题:
不能创建临时变量(第三个变量),实现两个数的交换。
cpp
//法一,但是在数过大时可能会出现错误
//int main()
//{
// int a = 0;
// int b = 0;
// scanf("%d%d", &a, &b);
// a = a + b;
// b = a - b;
// a = a - b;
// printf("%d %d\n", a, b);
// return 0;
//}
//法二
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);
//自己异或自己可以得到0
//任何数异或0都会得到自己本身
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("%d %d\n", a, b);
练习1:编写代码实现:求⼀个整数存储在内存中的⼆进制中1的个数。
cpp
方法一
//int NumberOf1(int n)
//{
// int count = 0;
// for (int i = 0; i < 32; i++)
// {
// if ((n & 1) == 1)
// {
// count++;
// }
// n = n >> 1;
// }
// return count;
//}
方法二
//int NumberOf1(unsigned int n)
//{
// int count = 0;
// while(n)
// {
// if (1 == n % 2)
// {
// count++;
// n = n / 2;
// }
// }
// return count;
//}
//
//方法三
//n&(n-1)会将n二进制中最后的1变为0
int NumberOf1(int n)
{
int count = 0;
while (n)
{
n = n & (n - 1);
count++;
}
return count;
}
int main()
{
int num = 0;
scanf("%d", &num);
printf("%d\n", NumberOf1(num));
return 0;
}
扩展:验证一个数是否为2的n次方的结果.
cpp
//因为2的n次方的二进制只有一个1,利用上题的解法3可得如果 n & (n - 1)为0则是
int main()
{
int n = 0;
scanf("%d", &n);
int m = n & (n - 1);
if (0 == m)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
return 0;
}
练习2:⼆进制位置0或者置1
编写代码将13⼆进制序列的第5位修改为1,然后再改回0
(置0需要在相应的二进制位上&0,其余位都&1(可以用~来实现,见代码)
置1需要在相应的二进制位上|1,其余位都|0)
cpp
int main()
{
int a = 13;
a = a | (1 << 4);
printf("%d ", a);
a = a & ~(1 << 4);
printf("%d ", a);
return 0;
}
单目操作符
单⽬操作符有这些: !、++、--、&、*、+、-、~ 、sizeof、(类型)(强制类型转换)
单⽬操作符的特点是只有⼀个操作数,在单⽬操作符中只有&和*没有介绍,这2个操作符,我们放在学习指针的时候学习.
逗号表达式
exp1, exp2, exp3, ...expN
逗号表达式,就是⽤逗号隔开的多个表达式。
逗号表达式,从左向右依次执行 .整个表达式的结果是最后⼀个表达式的结果.看下面代码以及执行结果:
下标访问[]、函数调用()
[ ] 下标引用操作符
操作数:⼀个数组名 + ⼀个索引值
int arr[10];//创建数组
arr[9] = 10;//实⽤下标引⽤操作符。
[ ]的两个操作数是arr和9。
函数调用操作符
接受⼀个或者多个操作数:第⼀个操作数是函数名,剩余的操作数就是传递给函数的参数. 函数调用操作符最少有一个操作数.
cpp
void test1()
{
printf("hehe\n");
}
void test2(const char* str)
{
printf("%s\n", str);
}
int main()
{
test1(); //这⾥的()就是作为函数调⽤操作符。
test2("hello bit."); //这⾥的()就是函数调⽤操作符。
return 0;
}
这些就是今天的复习内容啦,在下篇回复习下结构体及相关操作符和运算符的结合性与优先级和一些操作符运用不当导致错误的表达式求值.我们下篇博客见~