操作符是直接对内存里存储的值进行操作,而函数是更外层的操作方式。以操作整形变量举例:
在内存中,整数都是以补码形式存储的,所以操作符可以直接操纵内存中的补码的值,而printf函数打印的却是原码的值,显然经过了编译器的加工。
注:(正整数的原码,反码,补码是一致的。而负整数的原码以符号位+整数值,反码为符号位保留,其余位取反,补码为反码+1)
1.移位操作符
int a = 5;
int b = a>>1;
printf("%d\n,b");
其逻辑如下:
整型变量a向内存申请4个字节,32个bit存储该值。其存储形式如下:
补码:00000000000000000000000000000101
由移位操作符向右移一位(空位补0)
补码:00000000000000000000000000000010
原码:00000000000000000000000000000010
编译器将该值编译,结果显然为2
2
现在我们对负数进行同样的操作
int a = -5;
int b = a>>1;
printf("%d\n,b");
其逻辑如下:
整型变量a向内存申请4个字节,32个bit存储该值。其存储形式如下:
原码:10000000000000000000000000000101
反码:11111111111111111111111111111010
补码:11111111111111111111111111111011
由移位操作符向右移一位(空位补1)
补码:11111111111111111111111111111101
反码:11111111111111111111111111111100
原码:10000000000000000000000000000011
编译器将该值编译,结果显然为-3
-3
从结果上看,用位移操作符进行整型的操作,实际上左移就是原值乘以2,右移就是除以2的模。
2.位操作符
符号 | 名称 | 写法 |
& | 按位与 | 两真为真,一假为假 |
| | 按位或 | 一真为真,两假为假 |
^ | 按位异或 | 相同为真,相异为假 |
~ | 按位取反 |
实例
int main()
{
int a = 5;
int b = ~a;
printf("%d\n", b);
return 0;
}
结果为 -6
int main()
{
int a = -5;
int b = ~a;
printf("%d\n", b);
return 0;
}
结果为 4
释义
当a = 5时:
原码/补码:00000000000000000000000000000101
按位取反后
原码:11111111111111111111111111111010
反码:10000000000000000000000000000101
补码:10000000000000000000000000000110
内存中存储的是a = 5按位取反后的补码,显然为-6
当a = -5时:
原码:10000000000000000000000000000101
反码:11111111111111111111111111111010
补码:11111111111111111111111111111011
按位取反后
原码/补码:00000000000000000000000000000100
打印该补码,结果显然为4
编写代码实现:求一个(正负)整数存储在内存中的二进制中1的个数
#include<stdio.h>
int main()
{
int a = 0;
int count = 0;
int i = 0;
scanf("%d", &a);
for (i = 0; i < 32; i++)
{
if (1 == ((a >> i) & 1))
{
count++;
}
}
printf("count = %d\n", count);
return 0;
}
通过移位操作符,通过与00000000000000000000000000000001进行比较得到计数值。
摘下循环语句
for (i = 0; i < 32; i++)
{
if (1 == ((a >> i) & 1))
{
count++;
}
}
1)从i = 0开始计数,i<32,进入循环语句
2)a右移动0个,和1按位与,如果结果为1(右移动0位后末尾是1)
执行计数count++
3)i++
3.复合赋值操作符
略
4.单目操作符
sizeof() | 计算该类型在内存存储字节数 |
& | 取地址(与指针配套) |
-- | 前置(先赋值再操作)后置(先操作再赋值) |
~ | 按位取反 |
++ | 前置(先赋值再操作)后置(先操作再赋值) |
int/char/long | 强制转换数据类型 |
实例
int main()
{
int a = 1;
int b = 0;
b = a++;
printf("%5d%5d\n", a, b);
return 0;
}
结果 a为2,b为1
实例
int main()
{
int a = 1;
int b = 0;
b = ++a;
printf("%5d%5d\n", a, b);
return 0;
}
结果 a为2,b为2
5.关系操作符
符号 | |
< | |
> | |
== | |
!= |
关系操作符返回的是0或者1,常用于条件语句。
6.逻辑操作符
&& | 与 |
|| | 或 |
返回值是0或者1
实例
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
//a++ 先使用a的值0,再++, 判断a=0后,后面的 ++b && d++均不执行
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
return 0;
}
注:a++取出一个旧值,即a = 0中a的值,0,随后执行a++,a返回值为1.
&&语句接收返回值0,&&语句终止执行
结果为1,2,3,4
实例
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = ++a && ++b && d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
return 0;
}
改写以上代码,提取的是执行后的新值,a = 1.则&&后面的语句依次执行。
6.条件操作符
int main()
{
int a, b,max;
scanf("%d%d", &a,&b);
max = a > b ? a : b;
printf("%d\n", max);
return 0;
}
exp1?exp2:exp3
exp1返回值为1,执行exp2,否则执行exp3.
7.逗号表达式
exp1,exp2,exp3
最终返回exp3执行的值。