C语言-----操作符的分类

news2025/2/21 13:50:08

1. 操作符的分类

•算术操作符: + 、- 、 * 、/、%

移位操作符:<< >>

位操作符:  &  |  ^  `

赋值操作符:= / 、 % 、 += 、-= 、 *=、/=、 %=、 <<=、 >>=、&=、|= 、 ^=

单⽬操作符:!、 ++ 、- 、 & 、 * 、 + 、 、 ~ 、 sizeof 、 ( 类型 )

关系操作符:> 、 >= 、 < 、<= 、 == 、 !=

逻辑操作符:&& 、 ||

• 条件操作符: ? :

• 逗号表达式: ,

• 下标引⽤: []

• 函数调⽤: ()

• 结构成员访问: .->

2. ⼆进制和十进制转换

2进制

• 2进制中满2进1

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

比如“1101”

10进制

• 10进制中满10进1

• 10进制的数字每⼀位都是0~9的数字组成

2.1 2进制转10进制

10进制的123表⽰的值是⼀百⼆⼗三,为什么是这个值呢?其实10进制的每⼀位是权重的,10进 制的数字从右向左是个位、⼗位、百位....,分别每⼀位的权重是 10 ,10 ,10 ...

举个例子:

比如:二进制1111换为10进制

过程:2^3*1+2^2*1+2^1*1 +2^0*1  将各位的值相加:8 + 4 + 2 + 1 = 15。

二进制数1111转换为十进制数是15。

2.1.1 10进制转2进制数字

例如:5的二进制是101

2.2 2进制转8进制和16进制

2.2.1 2进制转8进制

16进制的数字每⼀位是0~9,a~f的,0~9,a~f的数字,各⾃写成2进制,最多有4个2进制位就⾜够了, ⽐如f的⼆进制是1111,所以在2进制转16进制数的时候,从2进制序列中右边低位开始向左每4个2进 制位会换算⼀个16进制位,剩余不够4个⼆进制位的直接换算。

如:2进制的01101011,换成16进制:0x6b,16进制表⽰的时候前⾯加0x

3. 原码、反码、补码

整数的2进制表示方法有三种,即原码、反码和补码

有符号整数的三种表⽰⽅法均有符号位和数值位两部分,2进制序列中,最⾼位的1位是被当做符号 位,剩余的都是数值位。

符号位都是⽤0表⽰“正”,⽤1表⽰“负”。

10000110  -6

00000110   6

正整数的原、反、补码都相同。

负整数的三种表示方法各不相同。

原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。

反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。

补码:反码+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;
 }

上面代码根据移位规则如下图所示:

10二进制1010经过移位变成10100,计算得20

4.2 右移操作符>>

移位规则:⾸先右移运算分两种:

1. 逻辑右移:左边⽤0填充,右边丢弃 

2. 算术右移:左边⽤原该值的符号位填充,右边丢弃

右移到底是算术右移,还是逻辑右移是取决于编译器的实现,常见的编译器都是算术右移

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

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

5. 位操作符:&、|、^、~

位操作符有:

1 &  //按位与
 
2 |  //按位或

3 ^  //按位异或
       
4 ~  //按位取反

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

5.1.按位与 &

#include <stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	int c = a & b;
	//3
	//补码:0000 0000 0000 0000 0000 0000 0000 0011
	//-5
	//原码:1000 0000 0000 0000 0000 0000 0000 0101
	//反码:1111 1111 1111 1111 1111 1111 1111 1010
	//补码:1111 1111 1111 1111 1111 1111 1111 1011
	//计算都是拿补码
	//0000 0000 0000 0000 0000 0000 0000 0011    3
	//1111 1111 1111 1111 1111 1111 1111 1011    -5
	//0000 0000 0000 0000 0000 0000 0000 0011   按位与得到补码
	printf("n= %d\n", c);
	return 0;
}

如何计算呢,两个补码两个同时唯1才得1,其他为0

5.2.按位或 |

#include <stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	int c = a | b; 
	//3
	//补码:0000 0000 0000 0000 0000 0000 0000 0011
	//-5
	//原码:1000 0000 0000 0000 0000 0000 0000 0101
	//反码:1111 1111 1111 1111 1111 1111 1111 1010
	//补码:1111 1111 1111 1111 1111 1111 1111 1011
	//计算都是拿补码
	//0000 0000 0000 0000 0000 0000 0000 0011    3
	//1111 1111 1111 1111 1111 1111 1111 1011    -5
	//1111 1111 1111 1111 1111 1111 1111 1011   按位或得到补码
	//经过计算
	//反码:1111 1111 1111 1111 1111 1111 1111 1010
	//原码:1000 0000 0000 0000 0000 0000 0000 0101  -5
	printf("n= %d\n", c);  //打印的是原码
	return 0; 
}

如何计算呢,两个补码有一则唯一,两个同时为0才为0

5.3.按位异或 ^ 

#include <stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	int c = a ^ b; 
	//3
	//补码:0000 0000 0000 0000 0000 0000 0000 0011
	//-5
	//原码:1000 0000 0000 0000 0000 0000 0000 0101
	//反码:1111 1111 1111 1111 1111 1111 1111 1010
	//补码:1111 1111 1111 1111 1111 1111 1111 1011
	//计算都是拿补码
	//0000 0000 0000 0000 0000 0000 0000 0011    3
	//1111 1111 1111 1111 1111 1111 1111 1011    -5
	//1111 1111 1111 1111 1111 1111 1111 1000   按位异或得到补码
	//经过计算
	//反码:1000 0000 0000 0000 0000 0000 0000 0111
	//原码:1000 0000 0000 0000 0000 0000 0000 1000  -8
	printf("n= %d\n", c);
	return 0; 
}

如何计算呢,两个补码相同为0相异为1

实现值交换

//a^a 相同为0
//0^a 0和任何数异或为任何数
#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	a = a ^ b;
	b = a ^ b;//a ^ b ^ b;b=a
	a = a ^ b;///a ^ b ^ b;->a ^ b ^ a;a=b
	printf("a = %d  b = %d\n", a, b);
	return 0;
}

5.4.按位取反 ~

#include <stdio.h>
int main()
{
	int a = 0;
	int b = ~a;
	//0000 0000 0000 0000 0000 0000 0000 0000
	//1111 1111 1111 1111 1111 1111 1111 1111 --补码
	//1000 0000 0000 0000 0000 0000 0000 0001 补码取反+1变成原码
	printf("n= %d\n", b);
	return 0;
}

计算一个数二进制数1个数:

#include <stdio.h>
int main()
{
	int a = 0;
	scanf("%d", &a);
	int count = 0;
	int i = 0;
	//原码:0000 0000 0000 0000 0000 0000 0000 1101 13
	//原码:0000 0000 0000 0000 0000 0000 0000 0001 1
	//由此可以看出任意一个数&1可以得到二进制最后一位是1或0
	for (i = 0; i < 32; i++)
	{
		if (a & (1 << i))
			//1经过左位移操作符,二进制里面一一直往前面移动
		{
			count++;
		}
	}
	printf("%d\n", count);
	
	return 0;
}

6. 单目操作符

单目操作符有这些:

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

7. 逗号表达式

1 exp1, exp2, exp3, …expN

逗号表达式,就是⽤逗号隔开的多个表达式。

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

//代码1 
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式 
c是多少?
由此得结果:13

//代码2 
if (a =b + 1, c=a / 2, d > 0)
逗号表达式从左向右计算,由此起到判断作用是d>0

8. 下标访问[]、函数调用引用()

8.1 []下标操作符

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

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

8.2 函数调用操作符

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

#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;
}

9. 结构成员访问操作符

9.1 结构体

C语言已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类 型还是不够的,假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不行的。描述⼀个学生需要 名字、年龄、学号、⾝⾼、体重等;描述⼀本书需要作者、出版社、定价等。C语言为了解决这个问 题,增加了结构体这种自定义的数据类型。

结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如: 标量、数组、指针,甚至是其他结构体。

9.1.1 结构的声明

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

9.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};//结构体嵌套初始化

9.2 结构成员访问操作符

9.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;
}
使⽤⽅式:结构体变量.成员名

9.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;
}
使用⽅式:结构体指针->成员名

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

C语⾔的操作符有2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。

10.1 优先级

优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是不⼀样的。
1 3 + 4 * 5;
上⾯⽰例中,表达式 3 + 4 * 5 ⾥⾯既有加法运算符( + ),⼜有乘法运算符( * )。由于乘法
的优先级⾼于加法,所以会先计算 4 * 5 ,⽽不是先计算 3 + 4

10.2 结合性

如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符 是左结合,还是右结合,决定执⾏顺序。⼤部分运算符是左结合(从左到右执⾏),少数运算符是右 结合(从右到左执⾏),⽐如赋值运算符( = )。
1 5 * 6 / 2;
上⾯⽰例中, * / 的优先级相同,它们都是左结合运算符,所以从左到右执⾏,先计算 5 * 6
再计算 6 / 2
来看一下符号优先级:

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

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

相关文章

PWM(脉宽调制)技术详解:从基础到应用实践示例

PWM&#xff08;脉宽调制&#xff09;技术详解&#xff1a;从基础到应用实践示例 目录 PWM&#xff08;脉宽调制&#xff09;技术详解&#xff1a;从基础到应用实践示例学前思考&#xff1a;一、PWM概述二、PWM的基本原理三、PWM的应用场景四、PWM的硬件配置与使用五、PWM的编程…

AI智能成长系统 | 应用探讨研究

研究背景 在现代家庭中&#xff0c;三岁宝宝的成长环境日益复杂。由于宝宝每天接触的人群多样&#xff0c;包括家庭成员、同龄小朋友以及可能的陌生人&#xff0c;其语言环境也相应地变得复杂多变。这种环境下&#xff0c;宝宝很容易接触到一些不适宜的语言&#xff0c;即俗称…

java 网络安全感知 网络安全学java

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 实验五 java网络编程及安全 实验内容 1&#xff0e;掌握Socket程序的编写&#xff1b;2&#xff0e;掌握密码技术的使用&#xff1b;3&#xff0e;设计安全传输…

VisionMaster4.4 python脚本 图像处理 转换函数 爱之初体验

最近有接触过一丢丢VM4.3的模块开发. 一直有把python图像处理部分模块移植进来的打算 不过时间不够没来得及折腾.偶尔发现4.4支持py脚本 于是拿来折腾.一下午. 发现4.4支持python脚本,好开心. 首先安装VM4.4 注意一定要是4.4 打开后拖了一个模块. 但是发现import numpy imp…

python-leetcode 40.二叉树的层序遍历

题目&#xff1a; 给定二叉树的根节点root,返回其节点值得层序遍历&#xff08;即逐层从左到右访问所有节点&#xff09; 方法&#xff1a;广度优先搜索 # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val0, leftNone, rightNon…

蓝桥杯学习大纲

&#xff08;致酷德与热爱算法、编程的小伙伴们&#xff09; 在查阅了相当多的资料后&#xff0c;发现没有那篇博客、文章很符合我们备战蓝桥杯的学习路径。所以&#xff0c;干脆自己整理一篇&#xff0c;欢迎大家补充&#xff01; 一、蓝桥必备高频考点 我们以此为重点学习…

小米AX3000T 路由器如何开启 SSH 安装 OpenWRT 系统,不需要降级 v1.0.91 (2025)

小米AX3000T 路由器如何开启 SSH 安装 OpenWRT 系统&#xff0c;不需要降级 v1.0.91 &#xff08;2025&#xff09; 本文内容需要你有一定的 Linux 操作基础&#xff0c;最好是程序员那种&#xff0c;英文水平足够用才行。一般人不需要使用这么复杂的路由器操作系统&#xff0c…

水基试剂,湿式化学,清水,干式化学,干粉,卤烃清洁剂,二氧化碳灭火器UL8检测报告标准讲解:

水基试剂&#xff0c;湿式化学&#xff0c;清水&#xff0c;干式化学&#xff0c;干粉&#xff0c;卤烃清洁剂&#xff0c;二氧化碳灭火器UL检测报告标准讲解&#xff1a; 本政策涵盖的灭火器 水基试剂灭火器 水基试剂灭火器使用水基试剂带走燃烧三要素中的热量要素&#xf…

汽车免拆诊断案例 | 2010 款路虎揽胜车空调偶尔出风异常

故障现象  一辆2010款路虎揽胜车&#xff0c;搭载5.0 L发动机&#xff0c;累计行驶里程约为16万km。车主反映&#xff0c;接通空调开关后&#xff0c;有时出风忽大忽小&#xff0c;有时不出风&#xff0c;有时要等2 min左右才出风&#xff1b;有时两三天出现一次&#xff0c;…

Mac arm架构使用 Yarn 全局安装 Vue CLI

dgqdgqdeMacBook-Pro spid-admin % vue --version zsh: command not found: vue要使用 Yarn 安装 Vue CLI&#xff0c;你可以执行以下命令&#xff1a; yarn global add vue/cli这个命令会全局安装 Vue CLI&#xff0c;让你可以使用 vue 命令创建、管理 Vue.js 项目。以下是一…

成员函数定义后面加const是什么功能:C++中const成员函数的作用

成员函数定义后面加const是什么功能&#xff1a;C中const成员函数的作用 前言C中const成员函数的作用总结 前言 在PX4的代码中的位置控制模块中&#xff0c;有这样一个成员函数 void getAttitudeSetpoint(vehicle_attitude_setpoint_s &attitude_setpoint) const;该函数的…

DeepSeek智能测试助手:分类+推理+导出一站式工具

前言 测试开发工程师在日常工作中需要处理大量测试文档&#xff0c;并且这些文档需要被高效分类、清洗和管理&#xff0c;同时结合强大的 AI 推理能力&#xff08;如 DeepSeek 模型&#xff09;进行智能化处理和分析。为此&#xff0c;我们开发了一款基于 PyQt5 的 GUI 工具&a…

计算机毕业设计Python农产品推荐系统 农产品爬虫 农产品可视化 农产品大数据(源码+LW文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

「正版软件」PDF Reader - 专业 PDF 编辑阅读工具软件

PDF Reader 轻松查看、编辑、批注、转换、数字签名和管理 PDF 文件&#xff0c;以提高工作效率并充分利用 PDF 文档。 像专业人士一样编辑 PDF 编辑 PDF 文本 轻松添加、删除或修改 PDF 文档中的原始文本以更正错误。自定义文本属性&#xff0c;如颜色、字体大小、样式和粗细。…

日期类(完全讲解版)

1. 类的设计思想 Date 类的设计目的是为了封装和处理日期信息&#xff0c;它提供了对日期的基本操作&#xff0c;如日期加减、日期比较、日期合法性检查等。类中的私有成员 int _year, int _month, int _day 存储了日期的年、月、日。 类的声明和构造 Date 类的声明&#xff1…

洛谷 P10726 [GESP202406 八级] 空间跳跃 C++ 完整题解

一、题目链接 P10726 [GESP202406 八级] 空间跳跃 - 洛谷 二、解题思路 我们要对输入的挡板进行排序&#xff0c;按高度从高到低&#xff08;从小到大&#xff09;。 排序之后s和t都要更新。 struct Baffle {int l, r;int h;int id; } b[1005];void Sort() {sort(b 1, b 1 n…

【设计模式精讲】创建型模式之工厂方法模式(简单工厂、工厂方法)

文章目录 第四章 创建型模式4.2 工厂方法模式4.2.1 需求: 模拟发放奖品业务4.2.2 原始开发方式4.2.3 简单工厂模式4.2.3.1 简单工厂模式介绍4.2.3.2 简单工厂原理4.2.3.3 简单工厂模式重构代码4.2.3.4 简单工厂模式总结 4.2.4 工厂方法模式4.2.4.1 工厂方法模式介绍4.2.4.2 工厂…

【ROS2】【ROS2】RViz2源码分析(八):Display中订阅ROS2消息(使用Qt信号和槽传递ROS2消息)

1、简述 RViz2 涵盖了 Qt 和 ROS2 的技术点,前面介绍 DisplaysPanel 时,主要分析了Qt相关部分,参见博客: 【ROS2】RViz2源码分析(七):DisplaysPanel 中的树状模型/视图 本篇博客,将会一起学习 RViz2 中如何使用 ROS2,以 Display 中订阅 ROS2 消息为例。 2、通过话题…

牛顿法:用泰勒级数求解平方根的秘籍

目录 一、引言二、牛顿法的理论基础——泰勒级数三、牛顿法的原理与推导3.1 原理概述3.2 推导过程3.3 几何解释 四、牛顿法的应用场景4.1 数值计算4.2 优化问题 五、牛顿法求平方根的具体案例5.1 原理推导5.2 具体步骤5.3 代码实现&#xff08;Python&#xff09;5.4 示例计算过…

Unity 打开摄像头 并显示在UI

需求: 打开相机并显示在UI上 效果: 注意&#xff1a; 电脑可能有多个摄像头&#xff0c;注意名称 代码: using System; using System.Linq; using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; #if UNITY_EDITOR using UnityEditor; #endifname…