【C语言回顾】操作符详解

news2024/10/6 14:35:18

  • 前言
  • 1. 操作符分类
  • 2. 二进制和进制转换
    • 2.1 二进制
    • 2.2 进制转换
      • 2.2.1 二进制转十进制
      • 2.2.2 二进制转八进制
      • 2.2.3 二进制转十六进制
  • 3. 原码、反码、补码
  • 4. 移位操作符
    • 4.1 左移操作符
    • 4.2 右移操作符
  • 5. 位操作符
  • 6. 单目操作符
  • 7. 逗号表达式
  • 8. 下标引用操作符
  • 9. 函数调用操作符
  • 10. 结构体和结构成员访问操作符
    • 10.1 结构体
      • 10.1.1 结构的声明
      • 10.1.2 结构体变量的定义和初始化
    • 10.2 结构成员访问操作符
      • 10.2.1 结构体成员的直接访问
      • 10.2.2 结构体成员的间接访问
  • 11. 操作符的属性:优先级、结合性
    • 11.1 优先级
    • 11.2 结合性
  • 12. 表达式求值
  • 结语


在这里插入图片描述


上期回顾: 【C语言回顾】函数递归
个人主页:C_GUIQU
专栏:【C语言学习】

在这里插入图片描述

前言

各位小伙伴大家好!上期小编给大家讲解了C语言中的函数递归,接下来详细讲讲操作符!
在这里插入图片描述

1. 操作符分类

  • 算术操作符: + 、- 、* 、/ 、%
  • 移位操作符: << 、>>
  • 位操作符: &、 | 、^
  • 赋值操作符: = 、+= 、 -= 、 *= 、 /= 、%= 、<<= 、>>= 、&= 、|= 、^=
  • 单⽬操作符: !、++、–、&、*、+、-、~ 、sizeof、(类型)
  • 关系操作符: > 、>= 、< 、<= 、 == 、 !=
  • 逻辑操作符: && 、||
  • 条件操作符: ? :
  • 逗号表达式: ,
  • 下标引用: []
  • 函数调用:()
  • 结构成员访问:. 、->

由于有⼀些操作符和⼆进制有关,所以我们先铺垫⼀下二进制和进制转换的知识。

2. 二进制和进制转换

2.1 二进制

  • 2进制中满2进1
  • 2进制的数字每⼀位都是0~1的数字组成

2.2 进制转换

2.2.1 二进制转十进制

【方法】基数乘以指数的n次方,以 2 为指数,进制值所在的位置为n(从0开始算起),进制值本身为基数。

在这里插入图片描述
【举例】

如下面列子:1010就是基数,其进制值的位置就是n。

在这里插入图片描述

2.2.2 二进制转八进制

【方法】

在这里插入图片描述
【举例】
在这里插入图片描述

2.2.3 二进制转十六进制

【方法】

  1. 从二进制数的最右边开始,将二进制数每四位分为一组。如果最左边的组不足四位,则在前面补零以使其成为四位。
  2. 将每组四位二进制数转换为其对应的十六进制数。
  3. 将所有十六进制数字连在一起,得到最终的十六进制数。

【举例】
在这里插入图片描述

3. 原码、反码、补码

【整数的2进制表示方法】原码、反码和补码
【符号位和数值位】2进制序列中,最⾼位的1位是被当做符号位(0正1负),剩余的都是数值位。

【概念】

  • 原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
  • 反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
  • 补码:反码+1就得到补码。

【性质】

  • 正整数的原、反、补码都相同。
  • 负整数的三种表示方法各不相同。
  • 补码得到原码也是可以使用“取反,+1”的操作。
  • 对于整形来说:数据存放内存中其实存放的是补码。

4. 移位操作符

在这里插入图片描述

4.1 左移操作符

【移位规则】左边抛弃、右边补0

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

在这里插入图片描述

4.2 右移操作符

【移位规则】

  1. 逻辑右移:左边⽤0填充,右边丢弃。
  2. 算术右移:左边⽤原该值的符号位填充,右边丢弃
#include <stdio.h>
int main()
{
	int num = 10;
	int n = num>>1;
	printf("n= %d\n",n);
	printf("num= %d\n",num);
	return 0;
}

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

5. 位操作符

& //按位与
| //按位或
^ //按位异或
~ //按位取反
//操作数都必须是整数

【示例】

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

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

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

6. 单目操作符

++
--
&
*
+
-
~ 
sizeof(类型)

比较简单,不过多赘述。

7. 逗号表达式

  • 逗号表达式,就是⽤逗号隔开的多个表达式。
  • 逗号表达式,从左向右依次执⾏。整个表达式的结果是最后⼀个表达式的结果。
//代码1
int a = 1;
int b = 2;
int c = (a>b,a=b+10,a,b=a+1);//逗号表达式
//c是多少?

//代码2
	if(a =b + 1,c=a / 2,d > 0)
	
//代码3
	a = get_val();
	count_val(a);
	while(a > 0)
{
	//业务处理
	//...
	a = get_val();
	count_val(a);
}

//如果使⽤逗号表达式,改写:
	while(a = get_val(),count_val(a),a>0)
	{
		//业务处理
	}

8. 下标引用操作符

操作数:⼀个数组名 + ⼀个索引值(下标)

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

9. 函数调用操作符

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

#include <stdio.h>
void test1()
{
	printf("hehe\n");
}
void test2(const char* str)
{
	printf("%s\n",str);
}
int main()
{
	test1(); //这⾥的()就是作为函数调⽤操作符。
	test2("hello bit.");//这⾥的()就是函数调⽤操作符。
	return 0;
}

10. 结构体和结构成员访问操作符

10.1 结构体

10.1.1 结构的声明

struct tag
{
	 member-list;
}variable-list;

【描述一个学生】

struct Stu
{
	 char name[20];//名字
	 int age;//年龄
	 char sex[5];//性别
	 char id[20];//学号
}; //分号不能丢

10.1.2 结构体变量的定义和初始化

//代码1:变量的定义
struct Point
{
	int x;
	int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//代码2:初始化。
struct Point p3 ={ 10, 20 };
struct Stu //类型声明
{
	char name[15];//名字
	int age; //年龄
};
struct Stu s1 ={ "zhangsan", 20 };//初始化
struct Stu s2 ={ .age=20, .name="lisi" };//指定顺序初始化
//代码3
struct Node
{
	int data;
	struct Point p;
	struct Node* next;
}n1 ={ 10, {4,5}, NULL }; //结构体嵌套初始化
struct Node n2 ={ 20, {5, 6}, NULL };//结构体嵌套初始化

10.2 结构成员访问操作符

10.2.1 结构体成员的直接访问

#include <stdio.h>
struct Point
{
	int x;
	int y;
}p ={ 1,2 };
int main()
{
	printf("x: %d y: %d\n",p.x,p.y);
	return 0;
}

10.2.2 结构体成员的间接访问

#include <stdio.h>
struct Point
{
	int x;
	int y;
};
int main()
{
	struct Point p ={ 3, 4 };
	struct Point* ptr = &p;
	ptr->x = 10;
	ptr->y = 20;
	printf("x = %d y = %d\n",ptr->x,ptr->y);
	return 0;
}
#include <stdio.h>
#include <string.h>
struct Stu
{
	char name[15];//名字
	int age; //年龄
};
void print_stu(struct Stu s)
{
	printf("%s %d\n",s.name,s.age);
}
void set_stu(struct Stu* ps)
{
	strcpy(ps->name,"李四");
	ps->age = 28;
}
int main()
{
	struct Stu s ={ "张三", 20 };
	print_stu(s);
	set_stu(&s);
	print_stu(s);
	return 0;
}

11. 操作符的属性:优先级、结合性

11.1 优先级

【优先级】如果⼀个表达式包含多个运算符,哪个运算符应该优先执行。
【示例】
表达式 3 + 4 * 5 ⾥⾯既有加法运算符( + ),⼜有乘法运算符( * )。由于乘法的优先级⾼于加法,所以会先计算 4 * 5 ,⽽不是先计算 3 + 4 。

11.2 结合性

如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符
是左结合,还是右结合,决定执⾏顺序。⼤部分运算符是左结合(从左到右执⾏),少数运算符是右 结合(从右到左执⾏),⽐如赋值运算符( = )。

圆括号( () )
• ⾃增运算符( ++ ),⾃减运算符( -- )
• 单⽬运算符( + 和 - )
• 乘法( * ),除法( / )
• 加法( + ),减法( - )
• 关系运算符( <> 等)
• 赋值运算符( = )
由于圆括号的优先级最⾼,可以使⽤它改变其他运算符的优先级。

12. 表达式求值

在C语言中,表达式的求值遵循特定的规则和运算符优先级。这些规则确保了表达式的求值顺序是一致的,无论表达式的复杂性如何。以下是一些基本的求值规则和概念:

  1. 运算符优先级:C语言中的运算符按照特定的优先级进行分组,优先级高的运算符先于优先级低的运算符进行求值。例如,乘法和除法的优先级高于加法和减法。
  2. 结合性:当表达式中存在多个相同优先级的运算符时,根据结合性决定求值的顺序。大多数运算符是左结合的,这意味着它们从左到右进行求值。例如,在表达式 a = b = c 中,b = c 先求值,然后将结果赋值给 a
  3. 括号:括号可以改变运算符的优先级,括号内的表达式首先被求值。例如,在表达式 (a + b) * c 中,首先求值 a + b,然后将结果与 c 相乘。
  4. 求值顺序:在C语言中,除了一些特殊情况(如逗号运算符和条件运算符),运算符的求值顺序是不确定的。这意味着在表达式 a++ + b 中,a++ 可能会在 b 之前、之后或同时被求值,这取决于具体的编译器实现。
  5. 副作用:表达式的求值可能会产生副作用,如修改变量的值(例如,a++*p = 42)。副作用的顺序也是不确定的,除非使用了序列点(sequence point),例如在表达式的末尾或逻辑与(&&)、逻辑或(||)运算符的求值过程中。
  6. 类型转换:在表达式中,如果操作数的类型不同,C语言会根据规则进行隐式类型转换,使得操作数具有相同的类型后再进行运算。
    例如,考虑以下C语言表达式:
int a = 5, b = 3, c = 2, d = 8;
int result = a * b + c / d;

求值步骤如下:

  1. 根据优先级,先进行乘法和除法:
    • a * b 结果为 15
    • c / d 结果为 0(因为C语言中的整数除法会向下取整)
  2. 然后进行加法:
    • 15 + 0 结果为 15
  3. 最后,将结果 15 赋值给变量 result

在实际编程中,理解这些规则对于编写正确且高效的代码至关重要。如果需要更精确的控制表达式的求值顺序,应该使用括号来明确指定。

结语

以上就是小编对操作符的详细讲解。
如果觉得小编讲的还可以,还请一键三连。互三必回!
持续更新中~!
在这里插入图片描述

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

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

相关文章

《ESP8266通信指南》4-以Client进行TCP通信(AT指令)

往期 《ESP8266通信指南》3-常用AT指令详解-8266连WIFI-CSDN博客 《ESP8266通信指南》2-ESP8266 AT测试-CSDN博客 《ESP8266通信指南》1-ESP8266 简介-CSDN博客 1. 小节目标 通过 AT 指令使用 8266 进行 TCP 通信 2. 书接上回 复习以下&#xff0c;上一小节我们讲到了 8…

ESP32开发

目录 1、简介 1.1 种类 1.2 特点 1.3 管脚功能 1.4 接线方式 1.5 工作模式 2、基础AT指令介绍 2.1 AT指令类型 2.2 基础指令及其描述 2.3 使用AT指令需要注意的事 3、AT指令分类和提示信息 3.1 选择是否保存到Flash的区别 3.2 提示信息 3.3 其他会保存到Flash的A…

数据结构(Wrong Question)

一、绪论 1.1 数据结构的基本概念 D 因为抽象数据类型&#xff08;ADT&#xff09;描述了数据的逻辑结构和抽象运算&#xff0c;通常用&#xff08;数据对象&#xff0c;数据对象&#xff0c;基本操作集&#xff09;这样的三元组来表示&#xff0c;从而可构成一个完整的数据结…

【笔记django】创建一个app

创建app 错误 raise ImproperlyConfigured( django.core.exceptions.ImproperlyConfigured: Cannot import rules. Check that dvadmin.rules.apps.RulesConfig.name is correct.原因 刚创建的rules的app被手动移动到了dvadmin目录下 而dvadmin/rules/apps.py的内容还是&…

文字转粤语语音怎么转?文字转语音

文字转粤语语音怎么转&#xff1f;文字转粤语语音的应用&#xff0c;不仅展现了现代科技的魅力&#xff0c;也为我们提供了更加便捷的交流方式。它们将文字转化为粤语发音&#xff0c;让我们能够更直观地感受粤语的韵味和魅力。同时&#xff0c;这些软件还具备高度的可定制性&a…

使用 FFMPEG 实现录屏和录音

FFmpeg 是一个非常强大的开源工具&#xff0c;它可以用来处理音频和视频。 要使用 FFmpeg 进行录屏和录音&#xff0c;需要首先确保你的系统已经安装了 FFmpeg。在大多数 Linux 发行版中&#xff0c;可以通过包管理器&#xff08;如 apt 或 yum&#xff09;来安装。在 Windows …

DNS 解析过程

一张图即可说明&#xff0c;如果能看到上图就不用往下看了。下面是上图的文字版解析 a. 用户输入 URL: 当你在浏览器中点击一个链接或输入一个网址时&#xff0c;比如点击一个图片链接 http://www.example.com/image.jpg&#xff0c;这个过程开始于你的设备尝试理解这个地址所…

(mac)Promethues监控之mysqld_exporter(MySQL监控)

搭建Mysqld_exporterPrometheusGrafana监控系统 普罗米修斯是后端数据监控平台&#xff0c;通过Mysqld_exporter收集mysql数据&#xff0c;Grafana将数据用图形的方式展示出来 前提&#xff1a;已安装grafana和promethues 1.下载安装Mysql &#xff08;1&#xff09;启动MySQL…

在 Slurm 上运行 Jupyter

1. 背景介绍 现在的大模型训练越来越深入每个组了&#xff0c;大规模集群系统也应用的愈发广泛。一般的slurm系统提交作业分为2种&#xff0c;一种是srun&#xff0c;这种所见即所得的申请方式一般适用于短期的调试使用&#xff0c;大概一般允许的时间从几个小时到1天左右&…

详细分析MySQL中的distinct函数(附Demo)

目录 前言1. 基本知识2. 基础Demo3. 进阶Demo 前言 该函数主要用于去重&#xff0c;对于细节知识&#xff0c;此文详细补充说明 1. 基本知识 DISTINCT 是一种用于查询结果中去除重复行的关键字 在查询数据库时&#xff0c;可能会得到重复的结果行&#xff0c;但有时只需要这…

AIGC时代之 - 怎样更好的利用AI助手 - 指令工程

爆火的AIGC 2022年11月30日&#xff0c;OpenAI发布ChatGPT 3 2022年12月4 日&#xff0c;ChatGPT 3 已拥有超过一百万用户 2023年各种大语言模型开始火爆全球 GPT们&#xff0c;已经成为了我工作和学习的非常重要的工具。 ChatGPT也没那么神奇&#xff1f; 不知道大家有没有…

JS----前端将列表数据转树型数据

前端将列表数据转树型数据 场景&#xff1a;后端返回列表数据&#xff0c;由前端根据业务需求完成树型数据转换&#xff0c; 常用于侧边导航菜单&#xff0c;下拉树型数据项等 export function listToTree(data: []) {var map: any {},tree: any []data.forEach((item: any…

virtualbox 网络设置实现主机和虚拟机互相访问

前言 一般来说&#xff0c;virtualbox 虚拟机的上网模式是 NAT。这样虚拟机可以上网并访问宿主机&#xff0c;但宿主机无法访问虚拟机&#xff0c;也无法 ping 通。下面介绍双网卡模式&#xff0c;实现虚拟机和宿主机能够互相访问 ping 通。 双网卡模式 进入虚拟机的网络设置…

【MySQL】A01、性能优化-语句分析

1、数据库优化方向 A、SQL及索引优化 根据需求写出良好的SQL&#xff0c;并创建有效的索引&#xff0c;实现某一种需求可以多种写法&#xff0c;这时候我们就要选择一种效率最高的写法。这个时候就要了解sql优化 B、数据库表结构优化 根据数据库的范式&#xff0c;设计表结构&…

webpack中mode、NODE_ENV、DefinePlugin、cross-env的使用

本文讲的全部知识点&#xff0c;都是和webpack相关的。如果你之前有疑问&#xff0c;那本文一定能帮你搞清楚。 问题来源一般是类似下面代码&#xff08;webpack.json中&#xff09;&#xff1a; "scripts": {"dev": "cross-env NODE_ENVdevelopmen…

【快速入门 LVGL】-- 5、Gui Guider界面移植到STM32工程

上篇&#xff0c;我们已学习&#xff1a;【快速入门 LVGL】-- 4、显示中文 工程中添加了两个按钮作示范。运行效果如图&#xff1a; 本篇&#xff1a;把Gui Guider设计好的界面&#xff0c;移植到STM32工程。 特别地&#xff1a; 在使用Gui Guider进行界面设计时&#xff0c;应…

探索SAVI:土壤调整植被指数的意义与应用

​随着遥感技术的不断发展&#xff0c;植被指数成为了评估地表植被覆盖和健康状况的重要工具之一。其中&#xff0c;SAVI&#xff08;Soil Adjusted Vegetation Index&#xff0c;土壤调整植被指数&#xff09;作为一种针对土壤表面反射率进行调整的植被指数&#xff0c;在土地…

Linux内核之hook机制:call_void_hook用法实例(六十一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

使用2023版BurpSuite半自动化Autorize进行垂直越权测试【图文教程】

本人在使用时BurpSuite v2023.12时&#xff0c;查阅网上资料&#xff0c;发现网上大多是旧版&#xff0c;而旧版跟新版在界面上有些许调整。故记录BurpSuite v2023.12使用教程&#xff0c;用于后续本人回顾。 Autorize工具安装 Extensions→BApp Store→Autorize→Download J…

HTML5+CSS3小实例:炫彩荧光线条登录框

实例:炫彩荧光线条登录框 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-sca…