C语言操作符与表达式详解

目录

操作符的分类:

(1)算数操作符

(2)移位操作符

(3)位操作符

(4)赋值操作符

(5)单目操作符

(6)关系操作符

(7)逻辑操作符

(8)条件操作符

(9)逗号表达式

(10)下标引用、函数调用和结构成员

表达式求值:

隐式类型转换

 整型提升

 算术转换

操作符的属性

运算符优先级和结合性表格:

一些问题表达式


操作符的分类:


(1)算数操作符

+(加)   -(减)   *(乘 )  /(除)   %(取余)

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

2.对于/操作符如果两个操作数都为整数,执行整数除法,而只要其中有一个浮点数执行的就是浮点数除法

int main() {/*int a = 6, b = 5;printf("%d", a / b);*/      //打印结果为1double a = 6.0;int b = 5;printf("%lf", a / b);      //打印结果为1.200000return 0;
}

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


(2)移位操作符

正数在内存中用原码(因与补码相同)表示,负数用补码

<<  左移操作符

移位规则:左边抛弃,右边补0

	int a = 2;//把a的二进制位向左移动一位(0010->0100)int b = a << 1;        //并不改变a的值printf("%d",b);        //打印结果为4

>>右移操作符

移位规则:

1.逻辑移位:左边用0补充,右边丢弃

2.算数移位:左边用原来的符号位填充,右边丢弃

int a = 10;//把a的二进制位向右移动一位(1010->0101)int b = a >> 1;         //并不改变a的值printf("%d", b);        //打印结果为4


(3)位操作符

&     //按位与

	int a = 3;int b = 5;//& - 按(2进制)位与int c = a & b;//0011 -a//0101 -b//0001 -c(对应位上同为1才为1,否则为0)printf("%d", c);        //打印结果为1

|      //按位或

    int a = 3;int b = 5;//| -按(2进制)位或int c = a | b;//0011 -a//0101 -b//0111 -c(对应位上同为0才为0,否则为1)printf("%d", c);        //打印结果为7

^     //按位异或

	int a = 3;int b = 5;// ^ -按(2进制)位异或int c = a ^ b;//0011 -a//0101 -b//0110 -c(对应位相同为0,相异为1)printf("%d", c);        //打印结果为6

注:他们的操作数必须是整数

异或操作的用途之一:不创建中间变量即可交换两个整型元素的值(同时保证交换过程中不发生范围溢出),例:

	//不创建中间变量交换a和b的值int a = 3;int b = 5;printf("a=%d, b=%d\n",a,b);a = a ^ b;b = a ^ b;a = a ^ b;printf("a=%d, b=%d\n",a,b);


(4)赋值操作符

  =   +=    -=   *=    /=   >>=   <<=   %=

连续的等号赋值是从左至右依次赋值:

	int a = 20;int x = 0;int y = 20;a = x = y + 1;printf("%d %d",a,x);//打印结果为21  21

复合赋值符的含义:

	int a = 10;a = 100;a += 100;//与a = a + 100等价//其他复合赋值符同理

注:C语言中一个=是赋值,两个=是判断


(5)单目操作符

!     逻辑反操作

	int flag = 5;//为真printf("%d\n", !flag);//打印结果为0(为假)flag = 0;//为假printf("%d\n", !flag);//打印结果为1(为真)

-     负值

将某数变为其相反数

int a=10;
a=-a;
printf("%d",a);//打印结果为-10

+     正值

 对操作数不做何改变

int a=10;
a=+a;
printf("%d",a);//打印结果为10

sizeof     操作数的类型长度(以字节为单位)

注: sizeof是一个操作符,不是函数

	int a = 10;int arr[10] = { 0 };printf("%d\n", sizeof(arr));//计算arr所占空间大小,单位是字节,打印结果为40,因为int类型大小是4个字节,数组有10个元素printf("%d\n", sizeof(int));//打印结果是4,可以直接对类型用sizeof

 注sizeof括号内的表达式不参与运算

	short s = 5;int a = 10;printf("%d\n", sizeof(s = a + 2));//打印结果为2(short类型大小为2个字节)printf("%d\n", s);//打印结果为5,sizeof括号内的表达式不参与运算

~     对一个数的二进制按位取反(包括符号位)

	int a = -1;//10000000000000000000000000000001 -原码//11111111111111111111111111111110 -反码//11111111111111111111111111111111 -补码// ~ 按位取反//00000000000000000000000000000000(补码按位取反)int b= ~a;printf("%d",b);//打印结果为0

 ++     前置、后置++

后置++:

	int a = 10;int b = a++;//后置++,先使用,再++printf("%d\n", a);//打印结果为11printf("%d\n", b);//打印结果为10

 前置++:

	int a = 10;int b = ++a;//前置++,先++,后使用printf("%d\n", a);//打印结果为11printf("%d\n", b);//打印结果为11

- -     前置、后置- -

 原理同++

int a = 10;
printf("%d\n", a--); //打印结果为10
printf("%d\n", a);//打印结果为9

*     间接访问操作符(解引用操作符)、 &     取地址操作符

int a = 10;printf("%p\n", &a);//& - 取地址操作符int *pa = &a;//pa是用来存放地址的 - pa就是一个指针变量*pa = 20;// * 解引用操作符 - 间接访问操作符printf("%d",a);//打印结果为20,*pa就代表着a

(类型)     强制类型转换

      int a = (int)3.14;//将3.14double类型变量强制转换为int类型printf("%d", a);//打印结果为3


(6)关系操作符

>

>=

<

<=

!=            用于测试“不相等”

==           用于测试“相等”

常用于判断语句中,较为简单


(7)逻辑操作符

&&                逻辑与

||                   逻辑或

    int a = 3;int b = 0;if (a && b) {//a和b同时为真时,才进入下面的语句printf("hello");//不执行此语句}if (a || b) {//a和b有一个为真,就进入下面的语句printf("world");//执行此语句}

:区分逻辑与按位与     区分逻辑或按位或

1&2---------->0             (0001和0010----->0000)

1&&2-------->1

1|2----------->3             (0001和0010----->0011)

1||2---------->1

 注:(表达式)1&&(表达式2)时,若(表达式1)=0,则(表达式2)不再计算

    int i = 0 , a = 0, b = 2, c = 3, d = 4;i = a++ && ++b && d++;printf("%d\n%d\n%d\n%d\n", a, b, c, d);//打印结果为 1 2 3 4

 注:(表达式)1||(表达式2)时,若(表达式1)=1,则(表达式2)不再计算

	int i = 0, a = 1, b = 2, c = 3, d = 4;i = a++ || ++b || d++;printf("%d\n%d\n%d\n%d\n", a, b, c, d);//打印结果为 2 2 3 4


(8)条件操作符

  又称作三目操作符

exp1 ?exp2 : exp3

exp1结果为真返回exp2,否则返回exp3

	int a = 3;int b = 0;//三目操作符b = (a > 5 ? 1 : -1);//表达式1 ?表达式2 :表达式3printf("%d", b);//打印结果为-1


(9)逗号表达式

exp1, exp2, exp3, ...expN

 逗号表达式 - 要向右依次计算,但是整个表达式的结果是最后一个表达式的结果

    int a = 3;int b = 5;int c = 0;//逗号表达式要向右依次计算,但是整个表达式的结果是最后一个表达式的结果int d = (c = 5, a = c + 3, b = a - 4, c += b);printf("%d",d);//结果为9


(10)下标引用、函数调用和结构成员

[ ]  :  下标引用操作符

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

	int arr[10];//创建数组arr[9] = 10;//实用下标引用操作符//[ ]的两个操作数是arr和9

( ):  函数调用操作符:接受一个或多个操作数

第一个 操作数是函数名,剩余的操作数就是传递给函数的参数

	int Add(int x, int y) {//函数的定义return x + y;}
	int a = 10;int b = 20;int ret = Add(a, b);//调用函数  () - 函数调用操作符

   访问一个结构的成员:

.            结构体.成员名

->         结构体指针->成员名

	//结构体//书:书名,书号,定价//创建了一个自定义的类型struct Book{//结构体的成员变量char name[20];char id[20];int price;};int num = 10;struct Book b = { "C语言","20191112537",55 };//结构体变量.成员名printf("%s\n", b.name);printf("%s\n", b.id);printf("%d", b.price);
	//结构体指针->成员名struct Book* pb = &b;printf("%s\n", pb->name);printf("%s\n", pb->id);printf("%d", pb->price);//输出结果与上方代码输出结果相同


表达式求值:

表达式求值的顺序一部分是由操作符的优先级和决定性决定。

同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。


隐式类型转换

C的整型算数运算总是至少以缺省整型类型的精度来进行的。

为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为

整型提升

(只有长度小于int长度(short、char)才进行整型提升)

	char a, b, c;//...a = b + c;

b和c的值被提升为普通整型,然后再执行加法运算。

加法运算完成之后,结果被截断,然后再存储于a中。

整型提升的意义:

具体例子:

    char a = 3;//00000011 - a(char只能存8个bite位)char b = 127;//01111111 - bchar c = a + b;//a和b都是char类型,都没有达到一个int的大小//这里会发生整型提升,高位补的都是符号位(无符号统一补0)//a整型提升后:00000000000000000000000000000011//b整型提升后:00000000000000000000000001111111//          c=00000000000000000000000010000010 //c发生截断,只存8个bite位,c = 10000010//此时c是char类型的变量,需要打印整型变量,再次发生整型提升//c - 11111111111111111111111110000010     (高位补符号位1)//但负数在内存中形式是补码,所以还要再求c的原码//c的原码 - 10000000000000000000000001111110 = -126printf("%d\n", c);//打印结果为-126
    char c = 1;printf("%u\n", sizeof(c));//1printf("%u\n", sizeof(+c));//4printf("%u\n", sizeof(-c));//4printf("%u\n", sizeof(!c));//4//%u是输出无符号整型数//+c  -c  !c  参与了运算,发生了整型提升,所以变为int的大小


 算术转换

  如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换位另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。

long  double

double

float

unsigned  long  int

long  int 

unsigned  int

int

上方从大至小排列

   如果某个操作数的类型在上面的这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算

	int a = 4;float f = 4.5f;a + f;//需要将a的类型转换为float类型去计算

注:算数转换要合理,不然存在一些潜在的问题

	float f = 3.14;int num = f;//会丢失精度


操作符的属性

复杂表达式的求值有三个影响的因素

1.操作符的优先级

2.操作符的结合性

3.是否控制求值顺序(如(表达式1)&&(表达式2):(表达式1)是0后(表达式2)不再计算))

两个相邻的操作符优先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。

	int a = 4;int b = 5;int c = a + b * 7;//优先级决定了计算顺序int c = a + b + 7;//优先级不起作用,结合性决定

运算符优先级和结合性表格:

(引用自博主星空之路Star的博客C语言34种运算符优先级及结合性)

一些问题表达式

注:有些表达式的运算顺序可能还是不唯一的

//表达式1
//a* b + c * d + e * f
//
//表达式的计算机可能是:
//a * b
//c * d
//a * b + c * d
//e * f
//a * b + c * d + e * f
//
//或者
//a * b
//c * d
//e * f
//a * b + c * d
//a * b + c * d + e * f//由于*比+的优先级高,只能保证*的计算是比+早,但是优先级并不能决定第三个*比第一个+早执行
	//表达式2int c=3; c + --c;//优先级只能保证--运算在+之前,无法得知+操作符的左操作数的获取在右操作数之前还是之后求值,所以结果不可预测,有歧义//2+2=4 或 3+2=5
	//表达式3int i = 1;int ret = (++i) + (++i) + (++i);printf("%d\n", ret);// VS里打印出12       gcc打印出10//因为VS中先算了三次++i,再将三个结果相加//而gcc中先算了两次++i,再相加,再执行++i,再相加(与上方表达式1原理类似)

  以上为C语言中操作符和表达式相关内容的详细讲解,感谢您花费宝贵的时间阅读本文章!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/613856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS 选择器全攻略:从入门到精通(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

pytorch11:模型加载与保存、finetune迁移训练

目录 一、模型加载与保存1.1 序列化与反序列化概念1.2 pytorch中的序列化与反序列化1.3 模型保存的两种方法1.4 模型加载两种方法 二、断点训练2.1 断点保存代码2.2 断点恢复代码 三、finetune3.1 迁移学习3.2 模型的迁移学习3.2 模型微调步骤3.2.1 模型微调步骤3.2.2 模型微调…

Asp .Net Core 系列: 集成 CORS跨域配置

文章目录 什么是CORS?Asp .Net Core 种如何配置CORS?CorsPolicyBuilder类详解注册以及使用策略三种方式EnableCors 和 DisableCors 特性关于带证书与不带证书代码的实现跨源&#xff08;cross-origin&#xff09;不带请求证书(Credentials)跨源&#xff08;cross-origin&…

c++析构函数

析构函数的简述 1. 析构函数和构造函数类似&#xff0c;是c规定当对象的生命周期结束时&#xff0c;默认你会调用析构函数。 2. 同理&#xff0c;当我们不写析构函数的时候&#xff0c;编译器会自动生成一个空实现的析构函数。 3. 析构函数只能编译器自己调用&#xff0c;我们…

CSS 选择器全攻略:从入门到精通(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

JavaScript从入门到精通系列第三十一篇:详解JavaScript中的字符串和正则表达式相关的方法

文章目录 知识回顾 1&#xff1a;概念回顾 2&#xff1a;正则表达式字面量 一&#xff1a;字符串中正则表达式方法 1&#xff1a;split 2&#xff1a;search 3&#xff1a;match 4&#xff1a;replace 知识回顾 1&#xff1a;概念回顾 正则表达式用于定义一些字符串的…

代码随想录算法训练营第二天|977 有序数组的平方、209长度最小的子数组、59 螺旋矩阵||

977 有序数组的平方 题目链接&#xff1a;有序数组的平方 思路 暴力解法 很容易想到的就是按照题目的说明&#xff0c;先给非递减数组中的每个元素做平方&#xff0c;然后使用一个排序函数对齐进行排序即可。 class Solution { public:vector<int> sortedSquares(ve…

IntelliJ IDEA Java 连接 mysql 配置(附完整 demo)

下载 MySQL 驱动 从MySQL官网下载JDBC驱动的步骤如下&#xff1a; 1&#xff09;访问MySQL的官方网站&#xff1a;MySQL 2&#xff09;点击页面上方的"DOWNLOADS"菜单&#xff1b; 3&#xff09;在下载页面&#xff0c;找到"MySQL Community (GPL) Downloads…

C++内存管理机制(侯捷)笔记2

C内存管理机制&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youtube: 侯捷-C内存管理机制 Github课程视频、PPT和源代码: https://github.com/ZachL1/Bilibili-plus 下面是第二讲allocator具体实…

11 双向链表

单链表的局限&#xff1a; 单链表的缺点&#xff1a;逆序访问单链表中的元素耗时大。&#xff08;时间复杂度&#xff1a;O&#xff09; 双向链表的定义 第0个节点【a1】的pre指针为NULL&#xff0c;要注意 插入操作&#xff1a; 删除操作&#xff1a; 初步实现双链表 代码&…

【Vue系列】Vue3快速构建项目,以及在已有代码情况首次打开如何初始化依赖项

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是是《前端》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌…

一天一个设计模式---适配器模式

概念 适配器模式是一种结构型设计模式&#xff0c;用于将一个类的接口转换成客户端所期望的另一个接口。它允许不兼容的接口之间进行协同工作&#xff0c;使得原本由于接口不匹配而无法合作的类能够一起工作。 具体内容 适配器模式主要包括以下几个要素&#xff1a; 目标接…

VBA中类的解读及应用第八讲:实现定时器功能的自定义类事件

《VBA中类的解读及应用》教程【10165646】是我推出的第五套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。 类&#xff0c;是非常抽象的&#xff0c;更具研究的价值。随着我们学习、应用VBA的深入&#xff0…

Java中输入和输出处理(三)二进制篇

叮咚&#xff01;加油&#xff01;马上学完 读写二进制文件Data DataInputStream类 FilFeInputStream的子类 与FileInputStream类结合使用读取二进制文件 DataOutputStream类 FileOutputStream的子类 与FileOutputStream类结合使用写二进制文件 读写二进制代码 package 面…

vue实现-年、月、日、时、分、秒、星期?

一、文章引导 #mermaid-svg-nP4oT3Y4d6oaxUsg {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-nP4oT3Y4d6oaxUsg .error-icon{fill:#552222;}#mermaid-svg-nP4oT3Y4d6oaxUsg .error-text{fill:#552222;stroke:#55222…

倍福(Bechhoff) CX8090嵌入式PC控制器开发没有想像中的那么难

笔者曾2023年初曾为云南阜外医院新风系统开发自动控制系统。医院所有新风设备和公区照明全部采用倍福嵌入式PC控制器实现智能控制。其中新风和供水计量通过CX8090实现控制&#xff1b;公区照明通过BC9050实现控制&#xff1b;并采用美国邦纳人机界面(THM035B&#xff09;实现远…

DB2除法的小数位问题(四舍五入问题)以及其他常用的函数

DB2除法的小数位问题&#xff08;四舍五入问题&#xff09;以及其他常用的函数 1. DB2取第一条数据2. DB2 中指定值排序2.1 使用case when2.2 使用decode函数 3. 拼接函数4. 强制转换类型——cast函数5. DB2除法的小数位问题&#xff08;四舍五入问题&#xff09;5.1 关于round…

three.js 关键帧动画

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div><div class"box-right"…

金和OA jc6 GetAttOut SQL注入漏洞复现

0x01 产品简介 金和OA协同办公管理系统软件(简称金和OA),本着简单、适用、高效的原则,贴合企事业单位的实际需求,实行通用化、标准化、智能化、人性化的产品设计,充分体现企事业单位规范管理、提高办公效率的核心思想,为用户提供一整套标准的办公自动化解决方案,以帮助…

语义解析:如何基于SQL去实现自然语言与机器智能连接的桥梁

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 语义解析 定义 作用 语义解析的应用场景 场景一&#xff1a; 场景二&#xff1a; 总结语…