目录
一、单目操作符
1、! 逻辑反操作
补充:布尔类型
2、& 取地址操作符
3、* 间接访问操作符(解引用操作符)
4、sizeof 计算操作数的类型长度
5、~ 操作符
操作符的结合使用
6、++操作符(前置/后置)
7、--操作符(前置/后置)
8、(类型) 强制类型转换
二、关系操作符
三、逻辑操作符
逻辑操作符经典例题
四、条件操作符(三目操作符)
五、逗号表达式
六、下标引用、函数调用和结构成员
1、下标引用操作符 [ ]
2、函数调用操作符 ( )
3、访问一个结构体的成员
一、单目操作符
单目操作符介绍
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置--、后置--
++ 前置++、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
1、! 逻辑反操作
真变假,假变真。
补充:布尔类型
• 布尔类型(_Bool/bool)就是用来表示真假的类型。
• 布尔类型只有两种取值:true 、 false
2、& 取地址操作符
取地址操作符一般都是对一个变量取地址。
#include <stdio.h>
int main()
{
int a = 10;
printf("%p\n", &a);//取出变量a的地址
int* pc = &a; //取出a的地址并存放在指针变量pc中,由于a是int类型,所以pc应该是int*
//类似的,还有字符型
char ch = 'a';
char* pc = &ch;
//数组
char arr[10] = { 0 };
char* p2 = arr; //arr是地址首元素的地址,取出数组首元素的地址
char* p3 = &arr[0];//同上
//对于常量字符串而言
char* p4 = "abcdef"; //取的是a的地址
printf("%c", *p4); //*p4就是a
return 0;
}
3、* 间接访问操作符(解引用操作符)
这个操作符是配合&来使用的
代码解析:首先取出a的地址存放到指针变量pc中,接着对pc前加个*叫做解引用,这时*pc就等价于a。初识C语言--指针篇(5),这篇博客后面也有讲到解引用操作符。
4、sizeof 计算操作数的类型长度
•首先sizeof既是关键词,也是操作符。
•它可以计算变量大小、数组大小、类型大小。
sizeof在计算一个变量名大小时,括号其实是可以省略(这从侧面上还能证明sizeof不是函数,因为在调用函数时,括号是不能省略的),但是计算类型大小时,括号不可以省略。
同样地,sizeof在数组也同样适用
接着,sizeof在计算中还有其他特点,看看下面的代码
代码解析:很多人想当然以为a+3=13,然后赋给b,最后b的值是13,实际上是错误的,那为什么是错误的呢?原因是sizeof内部的表达式是不参与计算的(a+3赋给b不会发生) 。所以b的值还是一开始的5,而为什么第8行打印的结果是2呢?原因很简单,a是整型占4个字节,而a+3中的3也属于整型,也占4个字节,而b是2个字节,但a+3的结果最终要放到b中,接着整型要存储到短整型会发生截断,所以表达式最终赋值的空间还是b说的算。
5、~ 操作符
~ 是对一个数的二进制所有位取反。
举个例子
代码解析:a的值为0,所以它的补码是00000000000000000000000000000000,又因为~是对二进制所以位取反,所以就变成11111111111111111111111111111111(补码),最后转换为原码(符号位不变,其他位按位取反,最后+1):10000000000000000000000000000001,最后的结果就是-1。
操作符的结合使用
既然我们学完了&、|、^、>>、<<、~ ,现在就把它们结合起来
在此之前如果没看过操作符(1),最好先看一遍哟
传送门:操作符详解(1)
问题如下:
先上代码,后面解释
代码解释:
那么问题来了,如何将最终目标改回9的二进制位呢?
老样子,先上代码
代码解析:
6、++操作符(前置/后置)
①后置++
计算规则:先使用,再++
代码解释:后置++,规则是先使用,则先使用a的值赋给b,所以b=10,接着再++,意思是让a自增1,所以a=11
②前置++
计算规则:先++,再使用
代码解析:前置++规则,先++,所以a先自增1,所以a=11,接着再使用,就是将a=11赋给b,所以b=11
7、--操作符(前置/后置)
-- 前置和后置就不细说了,本质上是和++相同的
--前置:先--,再使用
--后置:先使用,后--
8、(类型) 强制类型转换
举个例子
3.14是double类型,而a是int类型,但是编辑器就报警了,“初始化”:“double”转化到“int”可能会丢失数据, 为了避免这种情况,只需要对3.14强制类型转换。
二、关系操作符
>
>=
<=
!= 用于测试“不相等”
== 用于测试“相等”
这些关系运算符比较简单,没什么可以讲的,但是要注意一些运算符使用时候的陷阱
警告⚠:在编程过程中,不要把==(相等)和=(赋值)写错。
三、逻辑操作符
&& 逻辑与(并且)
|| 逻辑或(或者)
这里要与按位与(&)和按位或(|)区分:它们是通过二进制计算的
而逻辑与(&&)和逻辑或(||):只关注真假
逻辑与(&&)
•若a和b同时为真
a&&b的结果就为真
•若a和b中至少有一个为假
a&&b的结果就为假
总结:两真为真,一假为假
逻辑或(||)
•若a和b同时为真
a||b的结果就为真
•若a和b其中一个为真
a||b的结果就为真
总结:一真为真,两假才为假
为了让大家更好理解&&和||,举一个生活中的例子,假设a和b是一个女生求偶的条件,比如:a的条件是要有50w,b的条件是帅,对于&&来说,只要有一个不满足要求,女生就不会考虑,而对于||来说,是要有一个满足了,就可以牵手啦。
接下来看看一道经典例题
代码解析:先看44行代码,它是逻辑与操作符,首先先计算a++,而后置a++是先使用,后++,所以a++的值是0,为假(0为假,非0为真),对于逻辑与操作符,只要有一个为假,后面就没必要看了,但这里要注意的是,不管是前置++(--),还是后置++(--),它们都有副作用,虽然为假,但是a还是会自增1,所以最后a=1,b=2,c=3,d=4
如果把&&换成||,结果又会是如何呢?
代码解析:首先先计算a++,刚刚说过了为假,a自增了1为1,但是这里是逻辑或(||),一个假不能判定整个表达式全假,只有全假才算假,所以后面还要继续算,接下来++b是先计算,后使用,所以b自增1为3(非0为真),注意到这里为止,后面d++就没必要算了,逻辑或只要有一个为真,整个表达式都为真,所以打印结果就为a=1,b=3,c=3,d=4
四、条件操作符(三目操作符)
•exp1 ? exp2 : exp3 exp译为表达式
•若exp1为真,则exp2的结果就是整个表达式的结果,exp3不计算
•若exp1为假,则exp3的结果就是整个表达式的结果,exp2不计算
代码演示
求两个数的最大值
五、逗号表达式
•exp1 , exp2 , exp3 , ...expN
•逗号表达式,就是逗号隔开的多个表达式
•逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果
代码演示
代码解析:首先从左向右依次执行,虽然a>b为假,但不会影响后面的,接着把b+10的值赋给a,则a=12,最后,c的值就是最后b=a+1的值,所以b=12+1=13,也就是说c的值为13
六、下标引用、函数调用和结构成员
1)下标引用操作符 [ ]
操作数:一个数组名 + 索引值
2)函数调用操作符 ( )
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数是传递给函数的参数。
调用函数求字符串长度
3)访问一个结构体的成员
• . 结构体 . 成员名 传送门:初识结构体
• -> 结构体指针->成员名 传送门:指针结构体
这里简单总结
假如要定义一本书,所以要有书名、作者、出版社等等
①. 结构体 . 成员名
②• -> 结构体指针->成员名
这里其实还能用到点(.)操作符
到此为止,C语言中的操作符都讲完了。