初阶C语言-操作符上
“不飞则已,一飞冲天;不鸣则已,一鸣惊人。” 今天,我们一起来学习一下操作符的相关知识。
1.操作符分类
算术操作符
- * / %
移位操作符<< >>
位操作符& | ^
赋值操作符= = -= *= /=...
单目操作符! sizeof -- ...
关系操作符> >= < <= == !=
逻辑操作符&& ||
条件操作符? :
逗号表达式,
下标引用、函数调用和结构成员[] () ->
2.算术操作符
- * / %
注:1.除了
%
操作符之外,其他的几个操作符都可以作用于整数和浮点数。
2.对于/
操作符,如果两个数操作数都为整数,执行整数除法。而只要有浮点数,执行的就是浮点数的除法。
3.%
操作符的两个操作数必须为整数,返回的是整除之后的余数。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int m = 7 / 2;
printf("%d\n", m);
double n = 7.0 / 2;
printf("%lf\n", n);
int o = 7 % 2;
printf("%d\n", o);
return 0;
}
3.移位操作符
>>右移操作符 <<左移操作符
注:移位操作符的操作数只能是整数。
对于一个整数,是4个字节 = 32个比特位。一个整数写成二进制序列的时候,就是32个比特位。对于有符号的整数来说,最高位为符号位,符号位是1表示负数,符号位是0表示正数。
对于无符号数整数来说,没有符号位,所有位都是有效位。
整数的二进制表示形式有3种:原码、反码、补码。
原码:按照数值的正负,直接写出的二进制序列就是原码。
例如:10
这个数的原码
就是00000000000000000000000000001010
,那么-10
的原码就是10000000000000000000000000001010
。
注:对于正的整数,原码、反码、补码相同,无需计算。
对于负的整数,原码、反码、补码是需要计算的。
反码:原码的符号位不变,其他位按位取反。(按位取反,原来是0的改为1,原来是1的改为0)
补码:反码的二进制 1就得到补码。
因此,10
这个数的原码、反码、补码
都是00000000000000000000000000001010
。-10
的原码就是10000000000000000000000000001010
,反码是11111111111111111111111111110101
,补码是11111111111111111111111111110110
。整数在内存中存储的都是补码的二进制序列。 整数在计算的时候,使用的也是补码。
3.1左移位操作符
移位规则:左边抛弃,右边补0
#include <stdio.h>
int main()
{
//m:00000000000000000000000000000111
int m = 7;
int n = m << 1;
//左移位原则:左边抛弃,右边补0
//n:00000000000000000000000000001110
//n = 2 4 8=14
printf("%d\n", m);
printf("%d\n", n);
return 0;
}
我们可以发现左移位操作符可以起到加倍的作用。负数也是一样的道理:
3.2右移操作符
移位规则(右移运算分两种):
1.逻辑移位:左边用0填充,右边丢弃。
2.算术移位:左边用原该值的符号位填充,右边丢弃。
//右移位操作符
#include <stdio.h>
int main()
{
//a的原码:10000000000000000000000000001010
//a的反码:11111111111111111111111111110101
//a的补码:11111111111111111111111111110110
//大多数编译器采用的是算术右移
//b是算术右移(右边直接丢弃,左边补原符号位,原来是负数,左边补1,原来是正数,左边补0)
//b的补码:11111111111111111111111111111011
//b的反码:11111111111111111111111111111010
//b的原码:10000000000000000000000000000101
//b=-(1 4)=-5
int a = -10;
int b = a >> 1;
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}
我们可以看到,算术右移也起到了/2
的作用。
注:对于移位操作符,不要移动负数位,这个是标准未定义的。
4.位操作符
位操作符有:
|(按位或)&(按位与)^(按位异或)
注:他们的操作数必须是整数。
4.1按位与&
对于两个数a和b
,用按位与运算符求c = a&b;
,需要先写出a和b
的二进制位的补码形式,然后一个一个地对比,只有当两个数a和b的对应的补码都为1的时候,按位与的结果才是1,否则为0。
#include <stdio.h>
int main()
{
int a = 3;
int b = -5;
int c = a & b;//按(二进制)位与
//-5的原码:10000000000000000000000000000101
//-5的反码:10000000000000000000000000000100
//-5的补码:11111111111111111111111111111011
// 3的补码: 00000000000000000000000000000011
// 按位与:两个都为1才为1
// c: 00000000000000000000000000000011
//结果为3
printf("%d\n", c);
return 0;
}
4.2按位或|
对于两个数a和b
,用按位或运算符求c = a|b;
,需要先写出a和b
的二进制位的补码形式,然后一个一个地对比,只要当两个数a和b的对应的补码有一个为1的时候,按位或的结果就是1,否则为0。
#include <stdio.h>
int main()
{
int a = 3;
int b = -5;
int c = a | b;//按(二进制)位或
//-5的原码:10000000000000000000000000000101
//-5的反码:10000000000000000000000000000100
//-5的补码:11111111111111111111111111111011
// 3的补码: 00000000000000000000000000000011
// 按位或:有一个为1即为1
// c的补码: 11111111111111111111111111111011
// c的反码: 11111111111111111111111111111010
// c的原码: 10000000000000000000000000000101
//结果为-5
printf("%d\n", c);
return 0;
}
4.3按位异或^
对于两个数a和b
,用按位或运算符求c = a^b;
,需要先写出a和b
的二进制位的补码形式,然后一个一个地对比,两个数a和b的对应的补码相同为0,不同为1.
#include <stdio.h>
int main()
{
int a = 3;
int b = -5;
int c = a ^ b;//按(二进制)位异或
//-5的原码:10000000000000000000000000000101
//-5的反码:10000000000000000000000000000100
//-5的补码:11111111111111111111111111111011
// 3的补码: 00000000000000000000000000000011
// 按位异或:相同为0不同为1
// c的补码: 11111111111111111111111111111000
// c的反码: 11111111111111111111111111110111
// c的原码: 10000000000000000000000000001000
//结果为-8
printf("%d\n", c);
return 0;
}
注:特别地,a^a=0; a^0=a;
.
下面,我们给出一个特别的题:在不创建临时变量的情况下(没有第三个变量),实现两个数的交换。
通过前面的学习,我们知道在使用第三个变量是怎么实现的了:
//实现两个数的交换
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = 0;
printf("交换前a=%d,b=%d\n", a, b);
c = a;
a = b;
b = c;
printf("交换后a=%d,b=%d\n",a,b);
return 0;
}
那么,如果我们不使用第三个变量,该如何实现同样的功能呢?
//实现两个数的交换
#include <stdio.h>
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和b
的值很大的时候,就会出现溢出的问题。这里,我们就需要用到异或^
这个操作符了。
//实现两个数的交换
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
printf("交换前a=%d,b=%d\n", a, b);
a = a ^ b;//a=3^5;
b = a ^ b;//b=3^5^5=3
a = a ^ b;//a=3^5^3=3^3^5=5
//异或支持交换律
printf("交换后a=%d,b=%d\n", a, b);
return 0;
}
注:异或^
不存在溢出的问题,但是可读性不高,只限于整型的运算。
5.赋值操作符
赋值操作符用于在变量创建好之后对值的修改。
#include <stdio.h>
int main()
{
int a = 3;//不是赋值,是初始化
a = 10;//赋值
return 0;
}
赋值操作符可以连续使用,比如:
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int c = a = a b;//连续赋值
//连续赋值从右往左算
//a = a b = 30
//c = a = 30
printf("%d\n", c);
return 0;
}
但是,连续赋值的语句不利于调试,上述的int c = a = a b;
可以拆分成:
a = a b;
c = a;
//这样的写法更清晰爽朗且易于调试。
复合赋值符:
= -= *= /= %= >>= <<= &= |= ^=
这些运算符都可以写成复合的效果,例如:
int a = 2;
//以下两种写法表达含义一致
a = a 10;
a = 10;
6.单目操作符
6.1单目操作符的介绍
单目操作符 | 名称 |
---|---|
! | 逻辑反操作符 |
- | 负值 |
正值 | |
& | 取地址 |
sizeof | 操作数的类型长度(以字节为单位) |
~ | 对一个数的二进制按位取反 |
- - | 前置、后置- - |
前置、后置 | |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制类型转换 |
1.逻辑反操作符(!)
//0表示假,1表示真
#include <stdio.h>
int main()
{
int a = 1;
int b = 0;
b = !a;
printf("%d\n", b);
return 0;
}
2.解引用操作符(*)
//解引用操作符*
#include <stdio.h>
int main()
{
int a = 10;
int* p = &a;
*p;//对p解引用操作,*p是通过p中存放的地址,找到p指向的对象
//*p就是a
return 0;
}
3.sizeof和数组
//sizeof计算的是类型创建变量或变量的大小,单位是字节
//sizeof计算的结果是size_t类型的
//size_t是无符号的
//对size_t类型的数据进行打印,可以用%zd
//sizeof后面的括号在括号中写的不是类型的时候,括号可以省略,这样也说明了sizeof不是函数
//sizeof是操作符-单目操作符
#include <stdio.h>
int main()
{
int a = 10;
printf("%zd\n", sizeof(a));
printf("%zd\n", sizeof a);
printf("%zd\n", sizeof(int));
int arr[10] = { 0 };
printf("%zd\n", sizeof arr);
printf("%zd\n", sizeof(arr[1]));
return 0;
}
4.~(对一个数的二进制按位取反)
#include <stdio.h>
int main()
{
int a = 0;
printf("%d\n", ~a);
//a的补码: 00000000000000000000000000000000
// 按位取反,就是不论是不是符号位都取反
//~a的补码:11111111111111111111111111111111
//~a的反码:11111111111111111111111111111110
//~a的原码:10000000000000000000000000000001
// 符号位0为正 1为负
//~a的值为-1
return 0;
}
那么,接下来,可以看看~
怎么用?
#include <stdio.h>
int main()
{
int a = 10;
//000000000000000000000000000001010
//如果我们想让从右往左数第三个数变成1该怎么做?
// 即变成00000000000000000000000000001110为14
//将000000000000000000000000000000001左移二
//1<<2 00000000000000000000000000000100
//将左移后的二进制位与a的二进制位按位或即可
a |= (1 << 2);
printf("%d\n", a);
//那么,反过来,如果希望从右往左数第三个数再变为0该怎么办?
// 只需要将下面第一个和第二个按位与就能得到第三个
//0000000000000000000000000000001110
//1111111111111111111111111111111011,这个可以将(1<<2)取反得到
//0000000000000000000000000000001010
a &= ~(1 << 2);
printf("%d\n", a);
return 0;
}
5. --
操作符
#include <stdio.h>
int main()
{
int a = 2;
// a;
// 是一种自增1的操作
a ;
//前置 和后置 对于a本身没有影响,都是进行 1的操作
printf("%d\n", a);
return 0;
}
前置 和后置 对于a本身没有影响但是对于别人有影响!示例如下:
#include <stdio.h>
int main()
{
int a = 2;
int b = a ;
//后置 :先使用,后 1
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
#include <stdio.h>
int main()
{
int a = 2;
int b = a;
//前置 :先 1,后使用
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
前置--和后置--和前、后置 同理,大家可以自己试一下!
好啦,关于操作符的知识点就先讲到这里,后期会继续更新,欢迎大家持续关注、点赞和评论!
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgggaee
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13