C语言一操作符详解(各操作符介绍,表达式求值)
Posted SuchABigBug
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言一操作符详解(各操作符介绍,表达式求值)相关的知识,希望对你有一定的参考价值。
博观而约取,厚积而薄发。——《杂说送张琥》
操作符分类
一、算术操作符
+ - * / %
注意事项:
除了此符号 % 外,其他可用于整数和浮点数
% 操作符的两个操作数必须为整数。返回的是整除之后的余数。
对于操作符 / 如果两个操作数都为整数,执行整数除法。只要有符点数那么执行的就是符点数除法
这里的加和减没什么好说的但需要注意一下int的范围为-231 ~ 231-1,
也就是[-2147483648, 2147483647];
举例论证:
int a = 2147483647;
int b = 1;
printf("a + b = %d \\n", a + b); //a + b = -2147483648
int a1 = -2147483648;
int b1 = 1;
printf("a1 - b = %d \\n", a1 - b1 ); //a1 - b = 2147483647
对于除法如果用int进行接收那么即使有小数也会转换成整数,此时我们需要用double或者float类型进行接收,值也需要是浮点数
double a = 10.0;
double b = 3.0;
printf("a / b = %f\\n", a / b); // a / b = 3.333333
二、移位操作符
<< 左移操作符
>> 右移操作符
1. 左移操作符规则
上述num向左移动一个位,最左边丢弃一个0, 最右边补一个0
2. 右移操作符规则
I、逻辑右移
逻辑移位,左边补0,右边丢弃
II、算术右移
算术移位,左边用用原该值的符号位填充,右边丢弃
拿-1举例子:
-1存放在内存中是二进制的补码
整数的二进制表示形式有三种
原码:直接根据数值写出的二进制序列
反码:原码的符号位不变,其他位按位取反就是反码
补码:反码+1
-1的原反补:
原码:1000000 00000000 00000000 00000001
反码:1111111 11111111 11111111 11111110
补码:1111111 11111111 11111111 11111111
如果是逻辑右移,那么按照补码来看,最右边的1丢弃,最左边补0,就变成了一个非常大的数。
如果是算术右移,那么右边丢弃1,左边补1
三、位操作符
按位与 ---> & 举例:0 & 0 = 0, 1 & 0 = 0, 1 & 1 = 1
按位或 ---> | 举例: 0 | 0 = 0, 0 | 1 = 1, 1 | 1 = 1
按位异或 ---> ^ 举例: 0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 1 = 0
一道面试题:不能创建临时变量(temp),如何实现两个数的转换?
int a = 10;
int b = 20;
a = a + b;
b = a - b;
a = a - b;
printf("a is : %d \\n", a); // a is 20
printf("b is : %d \\n", b); // b is 10
//======================================
//========== 上述代码相加可能溢出 =========
//======================================
int x = 3;
int y = 5;
x = x ^ y;
y = x ^ y;
x = x ^ y;
printf("x is : %d \\n", x); // x is 5
printf("y is : %d \\n", y); // y is 3
有的人可能会想到两个数相加,但这不是最好的答案,因为我们在算术操作符中提到过int最大为231-1,考虑溢出,我们用异或来进行计算,我们来具体分析一下两个数是如何进行转换的
整数3用二进制表示为:011
整数5用二进制表示为:101
第一次异或: 011 ^ 101 = 110 // 6
第二次异或: 110 ^ 011 = 101 // y = 5
第三次次异或: 110 ^ 101 = 011 // x = 3
其实异或的本质就是相同为0,相异为1,就像上述的交换
实际上就是 x ^ y ^ y,那么第二次异或y和y为0,y得到x的值
相同道理,第三次异或x ^ y ^ x,那么只剩下y,x得到y的值
四、赋值操作符
简单来说,就是把右边的值赋值到左边放进变量进行存储
五、单目操作符
逻辑反操作 !
负值 -
正值 +
操作符的类型长度 sizeof
对一个数的二进制按位取反 ~
分为前值、后置 --
分为前值、后置 ++
解引用操作符 *
取地址 &
及强制类型转换
我们重点看一下取地址符和指针解引用
int a = 5;
printf("%p \\n", &a);
int* pa = &a;
printf("*pa : %d \\n", *pa);
*pa = 10;
printf("%d \\n", a);
这里的数字5需要存储,a变量在内存中需要开辟空间,开辟一个int型4个字节,而存储的空间则会化分为一个个小的内存单元,每个内存单元都有一个编号,而编号就是内存单元的地址,那么&a就是取a的地址。int* pa ,这里pa是用来存放地址的,pa就是一个指针变量,通过pa里面存放的地址,我们用*pa解引用来获取他所指向对象的值。通过 *pa也可以间接改变所指向a的内存空间的值。
sizeof和数组:
可以看到打印的结果,在传参之前,数组打印出来的sizeof如预期的显示所占空间的大小,但传给函数后进行sizeof打印,结果可能是4,也可能是8。因为数组中传过去的实际上是首元素的地址。那么指向这块内存的就是一个指针,4或者8取决于电脑是32位还是64位的。
六、关系操作符
> , >=
< , <=
!=
== 判断两个数是否相等
= 赋值
七、逻辑操作符
逻辑与 &&
逻辑或 ||
对于&&,如果逻辑与左边的条件为假的话,后面就继续判断了
int a = 0;
int b = 2;
int c = 3;
int i = 0;
i = a++ && ++b && ++c;
printf("a = %d\\n b = %d\\n c = %d\\n", a, b, c); // a = 1, b = 2, c = 3
上述的a为0,先使用后++,先判断a为假,后面就不做判断了,a自增后结束,因此结果为1 2 3
对于||,如果逻辑或左边的条件为真的话,后面就不用算了
int a = 0;
int b = 2;
int c = 3;
int i = 0;
i = a++ || ++b || ++c;
printf("a = %d\\n b = %d\\n c = %d\\n", a, b, c); // a = 1, b = 3, c = 3
结果为a = 1, b = 3, c = 3。可以看到a为后置++,先使用a,a为0,条件为假,a自增,继续向后判断,前值b加加后为3,条件为真,后面就不做判断了,因此结果为 1 3 3
八、条件操作符
三目操作符: a > b ? 1 : 0
这里的意思是a大于b吗?true返回1,否则为0
九、逗号表达式
逗号表达式应用场景:要从左向右依次计算,但是整个表达式的结果传给变量以最后一个为准。
int a = 10;
int b = 20;
int c = 30;
int d = (c +=20, a = c + 50, b /= 5, c+=a);
printf("d is %d \\n", d); //d is 150
十、下标引用、函数调用和结构成员
- [ ]下标引用操作符 ,操作数:一个数组名+一个索引值
- 函数调用操作符( ) ,一个函数callFunc( )
- 结构成员访问操作符分两种 . 和 ->
struct student{
char* name;
char gender;
int age;
};
int main(int argc, const char * argv[]) {
struct student henry = {"Leetcode King", 'M', 18};
printf("Student Name : %s \\n", henry.name);
printf("Student Gender : %c \\n", henry.gender);
printf("Student Age : %d \\n", henry.age);
struct student* ptr = &henry;
// printf("Student Name : %s \\n", (*ptr).name);
// printf("Student Gender : %c \\n", (*ptr).gender);
// printf("Student Age : %d \\n", (*ptr).age);
//下面为简化后
printf("Student Name : %s \\n", ptr->name);
printf("Student Gender : %c \\n", ptr->gender);
printf("Student Age : %d \\n", ptr->age);
return 0;
}
我们可以用.进行成员名访问,也可以创建结构体指针进行成员名的访问(*ptr),为了更加简单明了我们可以用->进行成员访问。
如果文章对你有帮助的话,给博主一键三连哦 Thank You~ 😃
以上是关于C语言一操作符详解(各操作符介绍,表达式求值)的主要内容,如果未能解决你的问题,请参考以下文章