操作符是直接对内存里存储的值进行操作,而函数是更外层的操作方式。以操作整形变量举例:

在内存中,整数都是以补码形式存储的,所以操作符可以直接操纵内存中的补码的值,而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执行的值。

8.操作符执行顺序

操作符详解(day13)_操作符