当前位置:网站首页>【c】操作符详解(二)
【c】操作符详解(二)
2022-08-04 09:22:00 【silence-Tan】
哈喽大家好,大家好,欢迎收看本期博客 !
我是Mr.tan
今天呢,给大家分享剩下的c语言中的操作符,希望对大家学习c语言能有所帮助。
一、赋值操作符
| 操作符: | 描述: | 用法案例: | 结合性: |
| = | 赋值 | a = 2 | R-L |
| += | 以……加 | a += 2 | R-L |
| -= | 以……减 | a -= 2 | R-L |
| *= | 以……乘 | a *= 2 | R-L |
| /= | 以……除 | a /= 2 | R-L |
| %= | 以……整数取余 | a %= 2 | R-L |
| >>= | 以……右移 | a >>= 2 | R-L |
| <<= | 以……左移 | a <<= 2 | R-L |
| &= | 以……与 | a &= 2 | R-L |
| |= | 以……或 | a |= 2 | R-L |
| ^= | 以……异或 | a ^= 2 | R-L |
1、赋值
对于赋值操作符,我们经常能用到,当我们对我们的身高和颜值不满意时,我们可以用赋值操作符来制定我们的目标。比如:
int tall = 175;//目前身高
tall = 185;//目标身高
int face_score = 70;//目前颜值分数
face_score = 90;//目标颜值分数2、连续赋值
当我们知道连续赋值的工作原理时,我们很容易理解,但是对于连续赋值也是有缺陷的,它不方便调试,当我们想观察每一步的细节时,它是观察不到位的。
int a = 10;
int b = 0;
b = a = a + 3;
所以未来大家在写代码的过程中,是不建议这种写法的,同样的语句我们可以分开写,这样不仅方便我们的调试,观察时也清晰。
int a = 10;
int b = 0;
a = a + 3;
b = a;
3、复合赋值
在看复合赋值之前,我们先观察下面两段代码:
//代码1
int main()
{
int a = 8;
a = a + 1;
printf("a=%d\n",a);
int b = 8;
b = b >> 2;
printf("b=%d\n", b);
int c = 8;
c = c * 3;
printf("c=%d\n", c);
int d = 8;
d = d | 1;
printf("d=%d\n", d);
return 0;
}
//代码2
int main()
{
int a = 8;
a += 1;
printf("a=%d\n",a);
int b = 8;
b >>= 2;
printf("b=%d\n", b);
int c = 8;
c *= 3;
printf("c=%d\n", c);
int d = 8;
d |= 1;
printf("d=%d\n", d);
return 0;
}
但我们仔细对比两个程序,我们会发现当我们对变量自身操作后,再将值赋给自己时,我们可以将常规写法改写成复合赋值的形式,这样就充分的运用了我们所学的知识。复合赋值中的其它操作符也能写成这样,在此我们就不一一列举了。
二、单目运算符
| 操作符: | 描述: | 用法案例: | 结合性: |
| ! | 逻辑反 | !a | R-L |
| + | 正号 | +3 | R-L |
| - | 负号 | -2 | R-L |
| & | 取地址 | &a | R-L |
| * | 解引用 | *pa | R-L |
| sizeof | 操作数类型长度 | sizeof(int) | R-L |
| ~ | 按位取反 | ~2 | R-L |
| ++ | 前、后缀自增 | ++2、2++ | (前缀)R-L(后缀)L-R |
| -- | 前、后缀自减 | --1、1-- | (前缀)R-L(后缀)L-R |
| () | 强制类型转换 | (int) 3.6 | R-L |
1、逻辑反操作
对于这个运算符,它的作用就是把真变成假,把假变成真(如图所示)。当我们看见第一段程序时,我们会发现if语句中的条件为假,将不运行printf语句。
//代码段1
int main()
{
int flag = 0;
if (flag)
{
printf("谭谭粉丝最帅!\n");
}
return 0;
}
//代码段2
int main()
{
int flag = 1;
if (!flag)
{
printf("谭谭粉丝最帅!\n");
}
return 0;
}

但是我们将if语句中的条件之前加上逻辑反操作的运算符,它将执行printf语句,并打印出“谭谭粉丝最帅!”(如图所示)。
int main()
{
int flag = 0;
if (!flag)
{
printf("谭谭粉丝最帅!\n");
}
return 0;
}![]()
2、正负号
对于正负号,我想大家应该是非常了解了吧!在变量的初始化时,我们可以给int、float、double等类型的值赋一个正数(正号省略不写),也可以赋一个负数(在变量之前加一个减号);
int main()
{
int a = -3 ;
int b = 4;
printf("a=%d b=%d\n",a,b);
return 0;
}
3、取地址符与解引用符
取地址符
创建变量的本质,一定是在内存中开辟一段存储空间。而内存中的每一个单元都有自己的编号,假设创建一个int类型的变量,那么整形变量中的4个字节都有自己的地址,如果我们想观察首个字节的地址,我们只需要在变量之前加一个&,而打印出来的结果是一个十六进制的数字。
int main()
{
int a = 10 ;
char b = 0;
printf("%p\n",&a);
printf("%p\n",&b);
return 0;
}
解引用
当我们想把这个数值存起来的时候,我们可以把它放进pa里面去,那么我们就可以把pa认为是一个指针变量,pa是专门用来存放a的地址。对于int* pa = 0这一语句中的*是告诉我们pa是指针变量,而它前面的int*是告诉我们pa所指的a的类型,而pa为变量名。pa里面存的是a的地址,当有一天我们想通过pa找到我们的a,只需要在pa的前面加上解引用操作符,如果单纯的只想得到a的地址,只需要pa即可。
int main()
{
int a = 10 ;
char b = 0;
int* pa = &a;
*pa = 20;
printf("%d\n", a);
printf("%p\n", pa);
return 0;
}
4、sizeof
sizeof是求操作数的类型长度的,而%zu是专门打印sizeof的返回值的。
int main()
{
int a = 10 ;
int* pa;
int arr[10];
printf("%zu\n",sizeof(a));
printf("%zu\n", sizeof(pa));
//sizeof(数组名),数组名表示整个数组,不是首元素的地址,它是求整个数组的大小,单位为字节
printf("%zu\n", sizeof(arr));
return 0;
}
int main()
{
short m = 5;
int a = 2;
printf("%zu\n", sizeof(m = a + 5));//sizeof内部放的表达式不计算
printf("%d\n", m);
return 0;
}对于代码段中的语句,a为int类型的变量,在内存中占用四个字节,m为short类型的变量,在内存中占两个字节。把a加5之后放到m中去会发生截断,因为把int类型的变量占用的内存空间比short类型大,它放不下,所以表达式最终会取决于short类型,而sizeof是求操作数的类型长度的,所以最后打印出来的结果前者为2。sizeof内部放的表达式不计算,所以打印出来的m为5

而对于sizeof的写法有三种形式:
//三种正确写法
printf("%zu\n",sizeof(a));
printf("%zu\n", sizeof a);
printf("%zu\n", sizeof(int));
//错误写法
printf("%zu\n",sizeof int);注意:如果sizeof后面为变量的类型,那么小括号是不能省略的,这是一种错误的写法,编译器会报错。
5、自增自减运算符
前置++与前置--
int main()
{
int a = 10;
int x = 0;
int y = 0;
x = ++a;
printf("%d\n", a);
//先对a进行自增,然后对使用a,也就是表达式的值是a自增之后的值。x为11。
y = --a;
printf("%d\n", a);
//先对a进行自减,然后对使用a,也就是表达式的值是a自减之后的值。y为10;
printf("%d %d", x, y);
return 0;
}
后置++与后置--
int main()
{
int a = 10;
int x = 0;
int y = 0;
x = a++;
printf("%d\n", x);
printf("%d\n", a);
//先对a先使用,再增加,这样x的值是10;之后a变成11;
y = a--;
printf("%d\n", y);
printf("%d\n", a);
//先对a先使用,再自减,这样y的值是11;之后a变成10;
return 0;
}
让我们通过一个例题来彻底学会自增自减的运算关系,当我们观察完代码之后请看下方的表格,表格中的各结果标明的非常清楚。
int main()
{
int a=2;
int b=2;
int c=2;
int d=2;
a++;
b--;
++c;
--d;
return 0;
}
| 表达式: | 表达式执行前变量值: | 表达式执行后变量值: | 表达式的值: |
| a++ | 2 | 3 | 2 |
| b-- | 2 | 1 | 2 |
| ++c | 2 | 3 | 3 |
| --d | 2 | 1 | 1 |
6、按位取反
int main()
{
int a = 3;
//00000000 00000000 00000000 00000011 按位取反前的补码
//11111111 11111111 11111111 11111100 按位取反后的补码
//11111111 11111111 11111111 11111011 按位取反后的反码
//10000000 00000000 00000000 00000100 按位取反后的原码
printf("%d\n", ~a);
return 0;
}~是对一个数的二进制按位取反 .将a按位取反后的原码转换为十进制数为-4,与我们打印出来的结果完全契合。

7、强制类型转换
(1)、将实数转换为整数时,系统采用的是截断方式,而不是4舍5入。
int main()
{
int a;
a = (int)3.8;
printf("%d\n", a);
return 0;
}

(2)、对变量进行强制类型转换后,变量的数据类型不变,而是得到一个所需类型的数据。
int main()
{
double x = 3.6;
int i;
i = (int)x;
//i为3,x为3.6,x为double型,i为整型。
printf("%d\n", i);
printf("%zu\n", sizeof(x));
printf("%zu\n", sizeof(i));
return 0;
}

三、关系操作符
| 操作符: | 描述: | 用法案例: | 结合性: |
| == | 等于 | 2 == 2 | L-R |
| > | 大于 | a > b | L-R |
| >= | 大于等于 | a >= c | L-R |
| < | 小于 | b < d | L-R |
| <= | 小于等于 | b <= f | L-R |
| != | 不等于 | a != f | L-R |
对于关系运算符,我想大家不管是在数学中还是在c语言中都已经再熟悉不过了,在这里要注意的有:
1、两个=为判断是否相等,而一个=为赋值,在写代码的过程中千万不要把它们搞混;
2、==不能比较两个字符串的内容,实际上比较的是两个字符串的首字符的地址;
3、关系运算符的优先级低于算术运算符,高于赋值运算符;
4、我们将判断的结果进行打印后, 1 为“真”,表示条件成立,而 0 为“假”,表示条件不成立。
四、逻辑运算符
| 运算符: | 描述: | 用法案例: | 结合性: |
| && | 逻辑与 | a && b | L-R |
| || | 逻辑或 | c || d | L-R |
1、逻辑与
//代码1
int main()
{
int a = 2;
int b = 4;
if (a && b)
{
printf("小比特,大梦想!");
}
return 0;
}
//代码2
int main()
{
int a = 2;
int b = 0;
if (a && b)
{
printf("小比特,大梦想!");
}
return 0;
}

逻辑或的两边同时为真,整个式子才为真,只要有一个为假,整个式子就为假。对于代码段中的表达式a&&b,先看a的值等不等于0,如果a等于0就不再计算b;如果a不等于0再去计算b;
2、逻辑或
//代码1
int main()
{
int a = 0;
int b = 4 - 4;
if (a || b)
{
printf("小比特,大梦想!");
}
return 0;
}
//代码2
int main()
{
int a = 2 + 3;
int b = 4 - 4;
if (a || b)
{
printf("小比特,大梦想!");
}
return 0;
}
对于逻辑或的运算,先判断逻辑或左边的表达式,当左边的表达式不等于0的时候就不要再计算右边的表达式,如果左边的表达式等于0的时候再计算右边的表达式即可。而逻辑或的两边只要有一个为真,整个式子就为真,如果两边都为假,则整个式子为假。
逻辑与的优先级别高于逻辑或,而他们两个都低于关系运算符,并且都高于赋值运算!
五、条件操作符
| 操作符: | 描述: | 用法案例: | 结合性: |
| ? : | 条件操作符 | a > b ? 2 : 3 | L-R |
int main()
{
int a = 3;
int b = 2;
int c;
c = ((a > b) ? 4 : -1);
printf("%d\n", c);
return 0;
}

如果a>b则c的值为4,否则c的值为-1;这段代码充分的展现了条件操作符的作用!
六、逗号表达式
| 操作符: | 描述: | 用法案例: | 结合性: |
| , | 逗号 | a=2+3,b=a-1,c=b*2 | L-R |
int main()
{
int a = 1;
int b = 2;
int c = (a =a + 2, b = b + 3, a = a + b,b = a + 1);
printf("%d\n", c);
return 0;
}
欢迎大家的收看本期内容,今天的内容到此结束了,对于c语言操作符的详解到这里就跟大家告别一段落了,让我们期待下一篇的文章到来吧!
如果喜欢,那就一键三连吧!!!
边栏推荐
- Inheritance and the static keyword
- 张朝阳对话俞敏洪:谈宇宙、谈焦虑、谈创业、谈退休、谈人生
- 2022-08-02 Analyze RK817 output 32k clock PMIC_32KOUT_WIFI to WiFi module clock register devm_clk_hw_register
- 区分惯性环节与延迟环节
- LVGL的多语言转换工具--字体设置的好助手
- 获取cpu的核数
- The separation configuration Libpq is supported, speaking, reading and writing
- Libtomcrypt AES 加密及解密
- OAK-FFC-4P全网首次测试
- 交换机链路聚合详解【华为eNSP】
猜你喜欢

冰蝎逆向初探

After four years of outsourcing, the autumn recruits finally landed
![Detailed explanation of switch link aggregation [Huawei eNSP]](/img/c2/f9797fe8b17a418466b60cc3dc50a1.png)
Detailed explanation of switch link aggregation [Huawei eNSP]

ps抠图怎么抠出来,自学ps软件photoshop2022,ps怎么抠出想要的部分-笔记记录

DOM简述

【云驻共创】HCSD 大咖直播–就业指南
![cannot import name 'import_string' from 'werkzeug' [bug solution]](/img/ee/c91ec761eb637260d92980a2838a92.png)
cannot import name 'import_string' from 'werkzeug' [bug solution]

架构设计杂谈

TiDB升级与案例分享(TiDB v4.0.1 → v5.4.1)

94后字节P7晒出工资单:狠补了这个,真不错...
随机推荐
已解决No module named ‘flask_misaka‘【BUG解决】
ZbxTable 2.0 重磅发布!6大主要优化功能!
leetcode动态规划系列(求路径篇)
Could you please talk about how the website is accessed?[Interview questions in the web field]
telnet远程登录aaa模式详解【华为eNSP】
SQL后计算的利器
用OpenGL绘制winXP版扫雷的笑脸表情
LeetCode中等题之设计循环队列
三层交换机配置MSTP协议详解【华为eNSP实验】
LVGL的多语言转换工具--字体设置的好助手
I am 37 this year, and I was rushed by a big factory to...
外包干了四年,秋招终于上岸了
Shared_preload_libraries cause many syntaxes not supported
Detailed explanation of NAT/NAPT address translation (internal and external network communication) technology [Huawei eNSP]
命里有时终须有--记与TiDB的一次次擦肩而过
MindSpore:MindSpore GPU版本安装问题
Detailed explanation of telnet remote login aaa mode [Huawei eNSP]
双指针方法
[Punctuality Atom STM32 Serial] Chapter 3 Development Environment Construction Excerpted from [Punctual Atom] MiniPro STM32H750 Development Guide_V1.1
IDEA 自动导入的配置(Auto import)