操作符详解1

本文详细介绍了C/C++中的各种操作符,包括算数操作符、移位操作符、位操作符、赋值操作符、单目操作符以及它们在实际编程中的应用。通过实例解释了位操作如何改变数字的二进制表示,并展示了如何利用位操作进行数字交换。同时,还探讨了单目操作符如逻辑非和按位取反的用法。
摘要由CSDN通过智能技术生成

一、操作符与表达式

分类:算数操作符、移位操作符、位操作符、赋值操作符、单目操作符、关系操作符、逻辑操作符、条件操作符、逗号操作符、 下标引用、函数调用和结构成员。

1、算数操作符

+    -    *    /    %

其中,%的两端必须为整数,返回的是整除后的余数;

/  两边的3和5都是整数,除法执行的是整数除法,得到的结果是整数,如果想要得到小数,那么这样写

 然而得到的结果是这个结果确不理想,所以如果想要得到正确的结果,/ 两端至少有一个数是浮点数,比如说

2、移位操作符

<<  左移操作符      >>  右移操作符

int main()
{
	int a = 2;
	int b = a << 1;//把a的二进制位向左移动一位
	printf("b=%d\n", b);
	return 0;
}

 2是整数,放在a中,a又是整型变量,占了4个字节,也就是32个比特位,32个比特位放2是

,向左移动一位,就是把a的二进制序列拿起来,向左移动一位左边的0丢弃,右边少一位则补0,此时1在的三位,这是整个数字变成了4,放在b中,这是的b就是4

我们可以得出一个结论:左移操作符规则是左边丢弃,右边补0.

那向右移动呢?

int main()
{
	int a = 10;
	int b = a >> 1;//把a的二进制位向右移动一位
	printf("b=%d\n", b);
	return 0;
}

 10的二进制序列

 这时把它拿起来右移一位后把右边超出部分舍弃,那么左边要怎么补呢?首先我们要知道,内存中存了二进制序列,最高位时0则代表这个数是正数,最高位是1则这个数是负数.

右移分为两种,一种是算数右移,另一种是逻辑右移;

算数右移:右边丢弃,左补原符号位;

逻辑右移:右边丢弃,左边补0.

我们先运行上边的代码

 

 一般来说,正数是看不出进行了什么右移,所以我们需要使用负数

int main()
{
	int a = -1;
	int b = a >> 1;//把a的二进制位向右移动一位
	printf("b=%d\n", b);
	return 0;
}

我们需要先知道,整数的二进制表示形式有3种,

1、原码:直接根据数值写出的二进制序列就是原码;

2、反码:原码的符号位不变,其他位按位取反就是反码;

3、补码:反码+1就是补码。

原、反、补码的算法是针对负数的,对于正整数,原、反、补码相同。

-1存放在内存中,存放的是二进制的补码

 要把-1向右移动一位,就是把补码向右移动一位

如果是算术右移就在左边补0,如果是逻辑右移就补1

 最终运行的结果是-1,所以当前的右移操作符使用的是算术右移。

 可以看出,a的结果没有发生变化。

3、位操作符

&  按位与
|  按位或
^  按位异或
注:它们的操作数必须是整数
int main()
{
	int a = 3;
	int b = 5;
	int c = a & b;//&-按(2进制)位与
	printf("%d\n", c);
	return 0;
}
//对应的二进制位按位与————对应的二进制位只要有0按位与的结果就是0,对应的二进制位两个都是1按位与的结果才是1。
a:00000000000000000000000000000011——3
b:00000000000000000000000000000101——5
c:00000000000000000000000000000001——1

最终结果

int main()
{
	int a = 3;
	int b = 5;
	int c = a | b;//|-按(2进制)位或
	printf("%d\n", c);
	return 0;
}
//对应的二进制位有真为真,两个为0则为0.
a:00000000000000000000000000000011——3
b:00000000000000000000000000000101——5
c:00000000000000000000000000000111——7

最终结果

int main()
{
	int a = 3;
	int b = 5;
	int c = a ^ b;//^——按(2进制)位异或
	printf("%d\n", c);
	return 0;
}
//对应的二进制位相同为0,相异为1
a:00000000000000000000000000000011——3
b:00000000000000000000000000000101——5
c:00000000000000000000000000000110——6

最终结果

那么,位操作有什么用途呢?

先看这一道题:不创建变量,两个数字交换,即a=3,b=5变成a=5,b=3.

法1、
int main()
{
	int a = 3;
	int b = 5;
	a = a + b;
	b = a - b;
	a = a - b;
	printf("a=%d b=%d", a,b);
	return 0;
}
//但是,这个写法有缺陷,数值太大会溢出
法2、
int main()
{
	int a = 3;
	int b = 5;
	printf("a=%d b=%d\n", a,b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

a^a=0——任何两个相同数字^为0

0^a=a——0和任何数异或还是它本身

a^b^b=a 可以看成先b^b,此时得到的是0;a^0的结果就是a。

int main()
{
    int a = 13;
    a = a | (1 << 4);
    printf("a=%d\n",a);
    return 0;
}

00000000000000000000000000001101——13
如果想把它变成00000000000000000000000000011101
则需要令00000000000000000000000000001101按位或00000000000000000000000000010000
00000000000000000000000000010000由1<<4产生的

4、赋值操作符

=

+=  -=  *=  /=  %=  >>=  <<=  &=  |=  ^=这些是复合操作符

int main()
{
    int a = 10;
    a = 100;
    a = a+100;
    a += 100;//和上一种写法是等价的
    a = a >> 3;
    a >> =3;
    return 0;   
}

注意:=是赋值;==是判断相等

5、单目操作符——只有一个操作数

!——逻辑反操作
int main()
{
    int flag = 5;
    //flag为真,打印hehe
    if (flag)
    {
        printf("hehe"\n);
    }
    //flag为假,打印haha
    if (!flag)
    {
        printf("haha"\n);
    }
    return 0;
}
sizeof
int main()
{
    int a = 10;
    char arr[10] = {0};
    printf("%d\n",sizeof(arr));//一个字符一个字节,10个就10个字节
    int arr[10] = {0};
    printf("%d\n",sizeof(arr));//一个字符4个字节,10个就40个字节
    printf("%d\n",sizeof(int [10]));//int [10]就是arr的类型

    printf("%d\n",sizeof(a));//计算a所占空间的大小,单位是字节
    printf("%d\n",sizeof(int));//(int)的括号不能省
    printf("%d\n",sizeof a );//证明了sizeof是操作符而不是函数,若为函数括号不能省
    return 0;
}
sizeof
int main()
{
    short s = 5;
    int a = 10;
    printf("%d\n",sizeof(s = a + 2));
    printf("%d\n",s)
    return 0;
}

打印结果:
2
5
//s = a + 2求出的结果是12放入s中,但sizeof计算的是s所占空间的大小,s是提前就开辟好的,所以表达式的结果由s说的算,所以算的结果为2

注:sizeof括号中放的表达式是不参与运算的。

~按位取反
int main()
{
    int a = -1;
    //100000000000000000000000000000001——原码
    //111111111111111111111111111111110——反码
    //111111111111111111111111111111111——补码
    int b = ~a;
    //111111111111111111111111111111111——补码
    //000000000000000000000000000000000
    printf("%d\n",b);   
    return 0;
}

练习:

int main()
{
    int a = 13;
    //把a的二进制为的第5位制成1
    a = a | (1 << 4);
    printf("a=%d\n",a);
    a = a &~ (1<<4);
    printf("a=%d\n",a);

//把a的二进制为的第5位制成0
00000000000000000000000000011101
按位与11111111111111111111111111101111
11111111111111111111111111101111由000000000000000000000000000010000按位取反得到
    
    return 0;
}
后置++
int main()
{
    int a = 10;
    int b = a++;//后置++,先使用,再++
    printf("%d\n",a);//11
    printf("%d\n",b);//10
    return 0;
}

前置++
int main()
{
    int a = 10;
    int b = ++a;//前置++,先++,再使用
    printf("%d\n",a);//11
    printf("%d\n",b);//11
    return 0;
}

int main()
{
    int a = 10;
    printf("%d\n",a--);//10
    printf("%d\n",a);//9
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值