【C语言】操作符和表达式

1、操作符

1. 算术操作符
+ - * / %
除了%操作符之外,其它的几个操作符可以作用于整数和浮点数
对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法
%操作符的两个操作数必须为整数,返回值为整除之后的余数
2. 移位操作符
移动的是二进制,数据在内存中以补码的形式进行保存。
正整数的原码、反码和补码相同。

负整数的原码、反码和补码如下 :(先绝对,再减一, 然后取反)

<< 左移操作符
 移位规则:左边抛弃,右边补0 ,左移操作相当于*2

>> 右移操作符
 右移运算分两种:
 1>逻辑移位:右边丢弃,左边用0填充
 2>算术移位:右边丢弃,左边补符号位
3. 位操作符 
& 按位与

| 按位或
^ 按位异或
Tips:操作数必须是整数

#include <stdio.h>
int main() {
 int num1 = 3; 
 int num2 = 5;
 int result1 = num1 & num2;
 printf("num1 & num2 = %d\n",result1);
 int result2 = num1 | num2;
 printf("num1 | num2 = %d\n", result2);
 int result3 = num1 ^ num2;
 printf("num1 ^ num2 = %d\n", result3);
}


3的二进制:00000000 00000000 00000000 00000011
5的二进制:00000000 00000000 00000000 00000101

按位与 &:

按位或 |

按位异或

不能创建临时变量(第三个变量),实现两个数的交换。
 

#include <stdio.h>
int main() {
 int a = 10;
 int b = 3;
 printf("交换之前:a=%d b=%d\n", a, b);
 /*a = a - b;
 b = a + b;
 a = b - a;*/
 // 使用^操作符
   a = a ^ b;
 b = a ^ b;
 a = a ^ b;
 printf("交换之后:a=%d b=%d", a, b);
}

练习:
编写代码实现:求一个整数存储在内存中的二进制1的个数。
// 方式1:利用10进制转二进制的方式
 

#include <stdio.h>
int main() {
 int num = 10;
 int count = 0;
 while (num) {
 count += num % 2;
 num = num / 2;
 }
 printf("%d二进制中1的个数=%d\n", num, count);
}

// 方式2:利用&运算符来实现(右移与循环)
 

#include <stdio.h>
int main() {
 int num = -1;
 int source = num;
 int count = 0;
 for (int i = 0; i < 32;i++) {
 if ((num >> i) & 1 == 1) {
 count++;
 }
 }
 printf("%d二进制中1的个数=%d\n", source, count);
}

//方法3:减一循环

#include <stdio.h>
int main() {
 int num = -1;
 int source = num;
 int count = 0;
 while (num) {
 count++;
 num = num & (num - 1);
 }
 printf("%d二进制中1的个数=%d\n", source, count);
}

4. 赋值操作符
赋值操作符可以让你对自己声明的变量重新赋值。
int weight = 80; // 体重
weight=58;
double salary = 10000;// 薪水
salary=25000; // 使用赋值操作符重新赋值
 注意:赋值操作符可以连续使用,比如:
int x = 10;
int y = 20;
int z = 30;
x = y = z + 1; // 连续赋值
但是,不建议连续使用,这样代码的可读性比较差,应该这样写:
y=z+1;
x=y;
复合赋值运算符:
+=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=


5. 单目操作符
就是在使用时只有一个操作数。

6. 关系操作符
<,>,<=,>=,==(等于),!=(不相等)
这些关系运算符比较简单,但是一定要注意相等的写法(==),不要写成=.


7. 逻辑操作符
&& 逻辑与
|| 逻辑或
区分逻辑与(或)和按位与(或)


8. 条件操作符(三目操作符)
exp1?exp2:exp3
f(a>5){
    b=3
}else {
    b=-3;
}
// 转换成条件表达式,应该如何写?
b=a>5?3:-3;

9. 逗号表达式
exp1,exp2,exp3,.....,expN
逗号表达式,就是用逗号隔开的多个表达式。逗号表达式,从左向右依次执行,整个表达式的结果是最后一个表达式的结果。

10. 下标引用、函数调用和结构成员
(1)下标引用操作符
int arr[10]={0};
arr[9]=20; // 数组名+下标通过下标引用操作符来操作数组成员
(2)函数调用操作符
通过函数名+参数的形式来调用函数。

int get_max(int a, int b) {
 return a > b ? a : b;
}
// 函数调用操作符
int max = get_max(a, b);

(3)访问一个结构的成员
. 结构体变量.成员名
-> 结构体指针->成员名

// 创建一个结构体类型----struct Stu
struct Stu {
  char name[20];
  int age;
  char id[20];
};
int main(){
  // 使用struct Stu这个类型创建一个学生变量stu,并初始化
  struct Stu stu = {"chatGpt",1,"c1001"};
  // 访问结构体成员,通过.操作符
  printf("%s\n",stu.name);
  printf("%d\n",stu.age);
  printf("%s\n",stu.id);
  
  struct Stu* p = &stu;
   // 访问结构体成员,通过->操作符
  printf("%s\n",p->name);
  printf("%d\n",p->age);
  printf("%s\n",p->id);
  return 0;
}

2、表达式求值

(1)隐式类型转换 
C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和short操作数在使用之前被转换为普通整型,这种转换称为整型提升。
(2)算术转换 
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
(3)操作符的属性 
复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?
 取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。
下面,我们来看看操作符的优先级,这是一张表:

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值