操作符详解

简介: C语言学习第十二弹

学习目标:


[x] 掌握 C 入门知识

学习内容:


一.操作符分类


操作符
算术操作符 + - * / %
移位操作符 << >>
位操作符 按位与(&)按位或()按位异或(^)
赋值操作符 = += -= *= /= %= >>= <<= &= ^=
单目操作符 !+ - & sizeof ~ - - ++ * (类型)
关系操作符 > < = >= <= != ==
逻辑操作符 逻辑与 逻辑或
条件操作符 exp1?exp2:exp3
逗号表达式 exp1,exp2,exp3, …expN
下标引用、函数调用和结构成员

二.操作符详解


1. 算术操作符


注意

1.除了%操作符之外,其他的几个操作符可以作用于整数和浮点数。

2.对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法(用%lf)。

3.%操作符的两个操作数必须为整数。返回的是整除之后的余数。

2. 转换


思考

如图上示例:

(1).为什么表示数值10的2进制位是1010呢?

二进制数、转换为十进制数的规律是:把二进制数按位权形式展开多项式和的形式,求其最后的和,就是其对应的十进制数——简称“按权求和”。

解:

=1×(2的3次方)+0×(2的2次方)+1×(2的1次方)+0×(2的0次方)

=8+0+2+0

=10

(2).为什么表示数值10的8进制位是12呢?

八进制转十进制是用按权相加法进行计算的,计算方法是将八进制每位上的数乘以位权,最后将得出来的数加在一起,结果就是转化完的十进制数字

解:

=1×(8的1次方)+2×(8的0次方)

=8+2

=10

(3).那么表示数值10的16进制位是什么呢?

(4).每四个二进制位可以换算成一个16进制

3. 移位操作符


移位操作符移动的是二进制的位

整数的二进制表示形式有3种:原码、反码、补码

整数在内存中存储的是补码

正整数的原码、反码、补码是相同的.

负整数的原码、反码、补码是(原码的符号位不变,其他位按位取反就是反码,反码+1就是补码)

原码:把一个数按照正负直接翻译成二进制就是原码

5,-5是整数,整数是存放在整型变量中的一个整型变量是4个字节-32比特位(一个字节等于8个比特位)

00000000000000000000000000000101(这是5)

10000000000000000000000000000101(这是-5)

最高的一位表示符号位0表示正数,1表示负数

反码:

补码:

由上知识可知:

-5的原码:10000000000000000000000000000101

-5的反码:11111111111111111111111111111010

-5的补码:11111111111111111111111111111011

左移:丢弃最高位(符号位同样丢弃),0补最低位

右移:

(1).算术右移:右边丢弃,左边用原来的符号位来填充

(2).逻辑右移:右边丢弃,左边直接用0填充

警告:

对于移位运算符,不要移动负数位,这个是标准未定义的。

例如下面这种就是错误的

int num = 10;
num >> -1;

4. 位操作符


(1).按位与:两个位都为1时,结果才为1


(2).按位或:两个位都为0时,结果才为0


(3).按位异或: 两个位相同为0,相异为1


5.赋值操作符


#include<stdio.h>
int main()
{
  int a = 3;
  a = a + 3;
  a += 3;
  a = a >> 3;
  a >>= 3;
  a = a ^ 5;
  a ^= 5;
  return 0;
}

6.单目操作符


#include<stdio.h>
int main()
{
  int flag = 5;
  if (flag) // flag为真
  {
  }
  if (!flag)// !flag为假
  {
  }
  return 0;
}
int main()
{
int a=10;
int* p = &a;//&取地址操作符
*p =20;//解引用操作符(间接访问操作符)
//int arr[10];
//&arr;//取出数组的地址
return 0;
}
#include<stdio.h>
int main()
{
  int a = 10;
  printf("%d\n", sizeof(a));
  printf("%d\n", sizeof(int));
  printf("%d\n", sizeof a);
  //printf("%d\n", sizeof int);//sizeof后面是类型则括号不能省略
  int arr[10] = { 0 };
  printf("%d\n", sizeof(arr));
  printf("%d\n", sizeof(arr[0]));
  return 0;
}
#include<stdio.h>
int main()
{
  int a = 0;
  //原码:00000000000000000000000000000000
  //反码:11111111111111111111111111111111
  //补码: 11111111111111111111111111111110
  //二进制按位取反:10000000000000000000000000000001
  printf("%d\n", ~a);
  return 0;
}

7.关系操作符


警告

在编程的过程中==和=不小心写错,导致的错误。

8.逻辑操作符


0为假,非0为真

逻辑与(&&):两个数中有一个为假,则判断为假

#include<stdio.h>
int main()
{
  int a = 3 && 5;
  printf("%d\n", a);
  return 0;
}结果为真所以运行结果是1
#include<stdio.h>
int main()
{
  int a = 3 && 0;
  printf("%d\n", a);
  return 0;
}结果为假所以运行结果是0

逻辑或(||):两个数中有一个为真,则判断为真

#include<stdio.h>
int main()
{
  int a = 3 || 0;
  printf("%d\n", a);
  return 0;
}因为3为真所以运行结果为真

注意

&&操作符左边为假,右边不再计算

||操作符左边为真,右边不再计算

#include<stdio.h>
int main()
{
  int i = 0, a = 0, b = 2, c = 3, d = 4;
  i = a++ && ++b && d++;
  printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);
  return 0;
}

因为a++先使用,a为0为假所以后面不用再计算了所以结果是 1234

#include<stdio.h>
int main()
{
  int i = 0, a = 1, b = 2, c = 3, d = 4;
  i = a++ || ++b || d++;
  printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);
  return 0;
}

因为a++先使用,a为1为真所以后面不用再计算了所以结果是 2234

9.条件操作符


exp1 ? exp2:exp3

如果表达式1为真,那么就计算表达式2,表达式2的结果为整个式子的 结果;

如果表达式1为假,那么就计算表达式3,表达式3的结果为整个式子的结果。


10.逗号表达式


逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。

#include<stdio.h>
int main()
{
  int a = 1;
  int b = 2;
  int c = (a > b, a = b + 10, a, b = a + 1);
  printf("%d\n", c);
  return 0;
}

a>b为假,对表达式不产生影响,a=b+10,所以a=12,b=a+1,所以b=13,又因为整个表达式的结果是最后一个表达式的结果所以c是13.

11.下标引用、函数调用和结构成员


(1).下标引用


1.[ ]下标引用操作符

操作数:一个数组名+一个索引值

#include<stdio.h>
int main()
{
  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
  printf("%d\n", arr[5]);
  return 0;
}

[ ]的两个操作数是arr和9。

(2).函数调用操作符


接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。

#include<stdio.h>
int main()
{
  int len = strlen("abc");//()函数调用操作符
  printf("%d\n", len);
  return 0;
}

(3).结构成员


#include<stdio.h>
struct S
{
  int num;
  char c;
};
void test(struct S* ps)
{
  //->结构成员访问操作符
  //结构体指针->结构体成员
  printf("%d\n", ps->num);
  printf("%d\n", ps->c);
}
int main()
{
  struct S s = {100,'b'};//结构体的初始化使用{}
  //打印结构中的成员数据:结构体变量.结构体成员名(. 操作符)
  printf("%d\n", s.num);
  printf("%d\n", s.c);
  test(&s);
  return 0;
}
相关文章
|
2月前
|
SQL 人工智能 关系型数据库
如何实现MySQL百万级数据的查询?
本文探讨了在MySQL中对百万级数据进行排序分页查询的优化策略。面对五百万条数据,传统的浅分页和深分页查询效率较低,尤其深分页因偏移量大导致性能显著下降。通过为排序字段添加索引、使用联合索引、手动回表等方法,有效提升了查询速度。最终建议根据业务需求选择合适方案:浅分页可加单列索引,深分页推荐联合索引或子查询优化,同时结合前端传递最后一条数据ID的方式实现高效翻页。
130 0
|
3月前
|
数据采集 人工智能 数据可视化
如何让AI写出高质量的数据分析报告?DataV-Note的评估体系揭秘
本文围绕DataV-Note智能分析创作平台的评估体系建设展开,旨在探索如何在AI技术快速发展的背景下,构建一套科学、可量化、多维度的数据分析报告评估体系。
218 10
|
3月前
|
算法 架构师 Java
Java 开发岗及 java 架构师百度校招历年经典面试题汇总
以下是百度校招Java岗位面试题精选摘要(150字): Java开发岗重点关注集合类、并发和系统设计。HashMap线程安全可通过Collections.synchronizedMap()或ConcurrentHashMap实现,后者采用分段锁提升并发性能。负载均衡算法包括轮询、加权轮询和最少连接数,一致性哈希可均匀分布请求。Redis持久化有RDB(快照恢复快)和AOF(日志更安全)两种方式。架构师岗涉及JMM内存模型、happens-before原则和无锁数据结构(基于CAS)。
93 5
|
7月前
|
人工智能 自然语言处理 算法
阿里云云市场专区在杭州数据交易所上线啦!
阿里云云市场专区在杭州数据交易所上线啦!
|
9月前
|
资源调度 监控 数据可视化
贝尔宾团队角色理论:高效团队的9种角色
贝尔宾团队角色理论将团队分为思考、行动、社交三类九种角色,明确角色定位可优化协作。
1452 0
贝尔宾团队角色理论:高效团队的9种角色
|
10月前
|
存储 供应链 安全
重塑信任:区块链技术如何打造数字世界的全新安全生态
【10月更文挑战第32天】区块链技术自比特币诞生以来,以其去中心化特性吸引了全球关注。本文通过最佳实践探讨区块链如何重塑数字世界的信任体系,包括保障数据真实性、身份验证与隐私保护以及提升投票系统的安全性和透明度。通过智能合约示例,展示了区块链在供应链管理、身份管理和投票系统中的应用。区块链技术正推动各行各业的创新与发展。
281 2
|
11月前
|
机器学习/深度学习 人工智能 自然语言处理
人工智能的未来:从机器学习到深度学习的演进
【10月更文挑战第8天】人工智能的未来:从机器学习到深度学习的演进
189 0
SpringMVC常见组件之HandlerMethodArgumentResolver解析-2
SpringMVC常见组件之HandlerMethodArgumentResolver解析-2
156 0
|
存储 监控 安全
Java基于物联网技术的智慧工地云管理平台源码 依托丰富的设备接口标准库,快速接入工地现场各类型设备
围绕施工安全、质量管理主线,通过物联感知设备全周期、全覆盖实时监测,将管理动作前置,实现从事后被动补救到事前主动预防的转变。例如塔吊运行监测,超重预警,升降机、高支模等机械设备危险监控等,通过安全关键指标设定,全面掌握现场安全情况,防患于未然。
332 5
|
移动开发 小程序 JavaScript
微信公众号借助小程序云函数实现支付功能
微信公众号借助小程序云函数实现支付功能
796 0